1. 程式人生 > >資料結構與演算法·實驗十

資料結構與演算法·實驗十

1.構造一棵二叉樹,樹的形態如下圖所示,打印出前序遍歷、中序遍歷、後序遍歷的遍歷序列。

2.選擇一種遍歷方式計算該樹中葉子結點的個數,並打印出葉子結點。

3.編寫一個查詢演算法,查詢資料“E”是否存在。


#include"stdlib.h"
#include"stdio.h"
typedef char DataType;
#include"BiTree.h"
#define MaxStackSize 100
/*typedef char ElemType;*/
typedef BiTreeNode* ElemType;
#include "SeqStack.h"
#include "LinQueue.h"

void main()
{
	BiTreeNode *root;
	Initiate(&root);
	if(root!=NULL)
		root=createbintree();
	printf("先序遍歷:");
	PreOrder(root,visit);  //先序遍歷
	printf("\n");
	printf("中序遍歷:");
	InOrder(root,visit);  //中序遍歷
	printf("\n");
	printf("後序遍歷:");
	PostOrder(root,visit);  //後序遍歷
	printf("\n");
	printf("二叉樹中結點個數為:%d\n",numofnode(root));
	printf("二叉樹中葉子結點個數為:%d\n",preleafnum(root));
	printf("\n/**************************************************************************************/\n\n");
    LayerOrder(root);
	printf("非遞迴先序遍歷:");
	PreOrderByStack(root);
	printf("非遞迴中序遍歷:");
	InOrderByStack(root);
	printf("佇列結構層序遍歷為:");
	LayerOrder2(root);
	printf("\n");
	Destroy(&root);
}
typedef struct Node
{
	DataType data;                /*資料域*/
	struct Node *leftChild;       /*左子樹指標*/
	struct Node *rightChild;      /*右子樹指標*/
}BiTreeNode;                      /*結點的結構體定義*/

void Initiate(BiTreeNode **root)  /*初始化建立二叉樹的頭結點*/
{
	*root=(BiTreeNode *)malloc(sizeof(BiTreeNode));
	(*root)->leftChild=NULL;
	(*root)->rightChild=NULL;
}

void Destroy(BiTreeNode **root)
{
	if((*root)!=NULL&&(*root)->leftChild!=NULL)
		Destroy(&(*root)->leftChild);
	if((*root)!=NULL&&(*root)->rightChild!=NULL)
		Destroy(&(*root)->rightChild);
	free(*root);
}

/*若當前結點curr非空,在curr的左子樹插入元素值為x的新結點*/
/*原curr所指結點的左子樹成為新插入結點的左子樹*/
/*若插入成功返回新插入結點的指標,否則返回空指標*/

BiTreeNode *InsertleftNode(BiTreeNode *curr,DataType x)
{
	BiTreeNode *s,*t;
	if(curr==NULL)
		return NULL;
	t=curr->leftChild;
	s=(BiTreeNode *)malloc(sizeof(BiTreeNode));
	s->data=x;
	s->leftChild=t;
	s->rightChild=NULL;
	curr->leftChild=s;
	return curr->leftChild;
}

BiTreeNode *InsertRightNode(BiTreeNode *curr,DataType x)
{                                          
	BiTreeNode *s,*t;
	if(curr==NULL)
		return NULL;
	t=curr->rightChild;       /*儲存原curr所指結點的右子樹指標*/
	s=(BiTreeNode *)malloc(sizeof(BiTreeNode));
	s->data=x;
	s->rightChild=t;          /*新插入結點的右子樹為原curr的右子樹*/
	s->leftChild=NULL;
	curr->rightChild=s;       /*新結點成為curr的右子樹*/
	return curr->rightChild;  /*返回新插入結點的指標*/
}

BiTreeNode *DeleteLeftTree(BiTreeNode *curr)  /*若curr非空,刪除curr所指結點的左子樹*/
{
	if(curr==NULL||curr->leftChild==NULL)
		return NULL;
	Destroy(&curr->leftChild);
	curr->leftChild=NULL;
	return curr;                              /*若刪除成功返回刪除結點的雙親結點指標,否則返回空指標*/
}

BiTreeNode *DeleteRightTree(BiTreeNode *curr)
{
	if(curr==NULL||curr->rightChild==NULL)
		return NULL;
	Destroy(&curr->rightChild);
	curr->rightChild=NULL;
	return curr;
}

void PreOrder(BiTreeNode *t,void visit(DataType item))
{
	if(t!=NULL)
	{
		visit(t->data);
		PreOrder(t->leftChild,visit);
		PreOrder(t->rightChild,visit);
	}
}

void InOrder(BiTreeNode *t,void visit(DataType item))
{
	if(t!=NULL)
	{
		InOrder(t->leftChild,visit);
		visit(t->data);
		InOrder(t->rightChild,visit);
	}
}

void PostOrder(BiTreeNode *t,void visit(DataType item))
{
	if(t!=NULL)
	{
		PostOrder(t->leftChild,visit);
		PostOrder(t->rightChild,visit);
		visit(t->data);
	}
}

void visit(DataType item)
{
	printf("%c",item);
}

void visit2(BiTreeNode *t)
{
	printf("%c",t->data);
}

BiTreeNode *createbintree(void)
{
	BiTreeNode *pbnode;
	char ch;
	scanf("%c",&ch);
	if(ch=='#')
		pbnode=NULL;
	else
	{
		pbnode=(BiTreeNode *)malloc(sizeof(BiTreeNode));
		if(pbnode==NULL)
			return pbnode;
		//InsertleftNode(pbnode,ch);
		pbnode->data=ch;
		pbnode->leftChild=createbintree();
		pbnode->rightChild=createbintree();
	}
	return pbnode;
}

int numofnode(BiTreeNode *t)
{
	if(t==NULL)
		return 0;
	else
		return(numofnode(t->leftChild)+numofnode(t->rightChild)+1);
}

int preleafnum(BiTreeNode *t)
{
	if(t==NULL)
		return 0;
	else
	{
		if((t->leftChild==NULL)&&(t->rightChild==NULL))
		{
			return 1;
		}
		return preleafnum(t->leftChild)+preleafnum(t->rightChild);
	}
}

/*int locate(BiTreeNode *t,DataType x)
{
	BiTreeNode *p;
	if(t==NULL)
		return 0;
	if(t->data==x)
		return 1;
	else
	{
		p=locate(t->leftChild,x);
		if(p)
			return 1;
		else
			return locate(t->rightChild,x);
	}
}*/

void LayerOrder(BiTreeNode *T)

{	int front=0,rear=1;
	BiTreeNode *a[100];
    a[0]=T;
	printf("非佇列結構層序遍歷為:");
    while(front<rear)
    {
        if(a[front])
        {
            printf("%c",a[front]->data);
			if(a[front]->leftChild!=NULL)
            {	a[rear++]=a[front]->leftChild;
			}
			if(a[front]->rightChild!=NULL)
            {	a[rear++]=a[front]->rightChild;
			}
            front++;
        }
        else
        {
            front++;
        }
    }
	printf("\n");
}

BiTreeNode *leftchild(BiTreeNode *p)
{
	if(p==NULL)
		return NULL;
	return p->leftChild;
}

BiTreeNode *rightchild(BiTreeNode *p)
{
	if(p==NULL)
		return NULL;
	return p->rightChild;
}


typedef struct qnode
{
	ElemType data;
	struct qnode *next;
}LQNode;

typedef struct
{
	LQNode *front;  /*隊頭指標*/
	LQNode *rear;   /*隊尾指標*/
}LQueue;

void QueueInitiate(LQueue *Q)  /*初始化鏈式佇列Q*/
{
	Q->rear=NULL;  /*定義初始隊尾指標下標值*/
	Q->front=NULL;  /*定義初始隊頭指標下標值*/
}

int QueueNotEmpty(LQueue Q)  /*判鏈式佇列Q非空否,非空則返回1,否則返回0*/
{
	if(Q.front==NULL) return 0;
	else return 1;
}

int QueueAppend(LQueue *Q,ElemType x)  /*把資料元素值x插入鏈式佇列Q的隊尾,入佇列成功則返回1,否則返回0 */
{
	LQNode *p;
	if((p=(LQNode *)malloc(sizeof(LQNode)))==NULL)
	{
		printf("記憶體空間不足!");
		return 0;
	}
	p->data=x;
	p->next=NULL;
	if(Q->rear!=NULL)
		Q->rear->next=p;
	Q->rear=p;
	if(Q->front==NULL)
		Q->front=p;
	return 1;
}

int QueueDelete(LQueue *Q,ElemType *d)  /*刪除鏈式佇列Q的隊頭資料元素值到d ,出佇列成功則返回1,否則返回0*/
{
	LQNode *p;
	if(Q->front==NULL)
	{
		printf("佇列已空無資料元素出佇列!\n");
		return 0;
	}
	else
	{
		*d=Q->front->data;
		p=Q->front;
		Q->front=Q->front->next;
		if(Q->front==NULL)
			Q->rear=NULL;
		free(p);
		return 1;
	}
}

int QueueGet(LQueue Q,ElemType *d)  /*取鏈式佇列Q的當前隊頭資料元素值到d ,成功則返回1,否則返回0*/
{
	if(Q.front==NULL)
	{
		printf("佇列已空無資料元素出佇列!\n");
		return 0;
	}
	else
	{
		*d=Q.front->data;
		return 1;
	}
}

void Destroy1(LQueue Q)
{
	LQNode *p,*p1;
	p=Q.front;
	while(p!=NULL)
	{
		p1=p;
		p=p->next;
		free(p1);
	}
}

void LayerOrder2(BiTreeNode *T)
{
	LQueue myQueue;
	BiTreeNode *Q;
	/*Initiate(&Q);*/
	QueueInitiate(&myQueue);
	QueueAppend(&myQueue,T);
	while(QueueNotEmpty(myQueue)==1)
	{
		QueueDelete(&myQueue,&Q);
		visit2(Q);
		if(Q->leftChild!=NULL)
			QueueAppend(&myQueue,Q->leftChild);
		if(Q->rightChild!=NULL)
			QueueAppend(&myQueue,Q->rightChild);
	}
}

typedef struct
{
	ElemType stack[MaxStackSize];
	int top;
}SeqStack;

void StackInitiate(SeqStack *S)  /*初始化順序堆疊S*/
{
	S->top=0;                    /*定義初始棧頂下標值*/
}

int StackNotEmpty(SeqStack S)    /*判順序堆疊S非空否,非空則返回1,否則返回0*/
{
	if(S.top<=0)
		return 0;
	else return 1;
}

int StackPush(SeqStack *S,ElemType x)  /*把資料元素值x壓入順序堆疊S,入棧成功則返回1,否則返回0 */
{
	if(S->top>=MaxStackSize)
	{
		printf("堆疊已滿無法插入!\n");
		return 0;
	}
	else
	{
		S->stack[S->top]=x;
		S->top++;
		return 1;
	}
}

int StackPop(SeqStack *S,ElemType *d)    /*彈出順序堆疊S的棧頂資料元素值到引數d ,出棧成功則返回1,否則返回0*/
{
	if(S->top<=0)
	{
		printf("堆疊已空無法插入!\n");
		return 0;
	}
	else
	{
		S->top--;
		*d=S->stack[S->top];
		return 1;
	}
}

int StackTop(SeqStack S,ElemType *d)   /*取順序堆疊S的當前棧頂資料元素值到引數d ,成功則返回1,否則返回0*/
{
	if(S.top<=0)
	{
		printf("堆疊已空!\n");
		return 0;
	}
	else
	{
		*d=S.stack[S.top-1];
		return 1;
	}
}

void PreOrderByStack(BiTreeNode *root)
{
	SeqStack s;
	BiTreeNode *p=root;
	StackInitiate(&s);
	while(StackNotEmpty(s)||p)  //StackNotEmpty(SeqStack S)
	{
		if(p)
		{
			visit2(p);
			StackPush(&s,p);  //StackPush(SeqStack *S,DataType x)
			p=leftchild(p);
		}
		else
		{
			StackPop(&s,&p);  //StackPop(SeqStack *S,DataType *d)
			p=rightchild(p);
		}
	}
	printf("\n");
}

void InOrderByStack(BiTreeNode *root)
{
    SeqStack s;
	BiTreeNode *p=root;
	StackInitiate(&s);
	while(StackNotEmpty(s)||p)  //StackNotEmpty(SeqStack S)
	{
		if(p)
		{
			//visit(p);
			StackPush(&s,p);  //StackPush(SeqStack *S,DataType x)
			p=leftchild(p);
		}
		else
		{
			StackPop(&s,&p);  //StackPop(SeqStack *S,DataType *d)
			visit2(p);
			p=rightchild(p);
		}
	}
	printf("\n");
}


相關推薦

資料結構演算法·實驗

1.構造一棵二叉樹,樹的形態如下圖所示,打印出前序遍歷、中序遍歷、後序遍歷的遍歷序列。 2.選擇一種遍歷方式計算該樹中葉子結點的個數,並打印出葉子結點。 3.編寫一個查詢演算法,查詢資料“E”是否存在。 #include"stdlib.h" #include"stdio

Python-資料結構演算法一、字典(對映)——基於兩種不同的底層實現)

保證一週更兩篇吧,以此來督促自己好好的學習!程式碼的很多地方我都給予了詳細的解釋,幫助理解。好了,幹就完了~加油! 宣告:本python資料結構與演算法是imooc上liuyubobobo老師java資料結構的python改寫,並添加了一些自己的理解和新的東西,liuyubobobo

資料結構演算法 提高二叉搜尋樹的效率

/*寫一個程式以實現插入、刪除且遍歷線索二叉搜尋樹,這裡樹中的每個節點包含一個字典程式。*/ using System; using System.Text; namespace Threads { class Node { /*兩個線索域;lthread,rthread;1

資料結構演算法·實驗

1、利用順序棧將一個非負的十進位制整數N轉換為對應的B進位制數。    要求:非負的十進位制整數N和B都從鍵盤輸入;轉換結果從螢幕輸出。 2、括號匹配問題,編寫一個判別表示式中括號是否正確配對的函式,並設計一個測試主函式。 #include<stdio.h>

資料結構演算法二)並查集(Union Find)

本文主要包括以下內容: 並查集的概念 並查集的操作 並查集的實現和優化 Quick Find Quick Union 基於size的優化 基於rank的優化 路徑壓縮優化 並查集的時間複雜度 並查集的概念 在電腦科學中,並查集 是一種樹形的資料結

資料結構演算法一 圖

視訊課堂https://edu.csdn.net/course/play/7621 目標. 在本章中,你將學習到: 圖相關的概念 實現圖 應用圖解決程式設計問題

資料結構演算法實驗題 素數區間

★實驗任務 dark di 在做數學題目的時候發現了一個現象,2 個相鄰的素數之間存在一 個區間,他把這個區間稱為非素數區間,那麼 dark di 想知道,給定一個正整數 x,x 所在的非素數區間長度是多少呢? 例如 23 和 29 是 2 個相鄰的素數,他們之

資料結構演算法) 二叉樹 前序遍歷 中序遍歷 後序遍歷

名詞解釋  度數(degree) 一個結點的子樹個數  樹葉(leaf) 沒有子樹的結點稱為樹葉或終端結點  分支結點(branch node) 非終端結點  子女(child)和兒子(son)非終端結點  父母(parent)若

資料結構演算法

連結串列的操作(遍歷、查詢、清空、銷燬、求長度、增加、刪除) 建立一個連結串列:需要三個指標(頭指標、始終指向尾節點的指標(剛開始讓其指向頭結點)、新創節點指標) 遍歷:需要一個指標P,剛開始指向首節點,用while(NULL!=P)來迴圈,在迴圈裡面更新指標P,P = P->pNex

資料結構演算法·實驗

求二叉樹的層序遍歷問題 要求:(1)編寫一個建立二叉樹的函式。 (2)編寫按層次(同一層自左至右)輸出二叉樹中所有的結點的函式。            (3)編寫一個測試主函式。 #include<stdlib.h> #include<stdio.h&

資料結構演算法)線段樹(Segment Tree)入門

本文主要包括以下內容: 線段樹的概念 線段樹的基本操作 實現一個線段樹 LeetCode相關線段樹的問題 線段樹的概念 線段樹(Segment Tree)也是一棵樹,只不過元素的值代表一個區間。 常用區間的 統計 操作,比如一個區間的最大值(ma

哈工大資料結構演算法實驗4

實驗要求 寫一個快速排序演算法,實現資料的快速排序 思路 隨便網上都能找到快排演算法,然後照抄就ok。。。當然理解快排是必要的,只是快排不是很好理解,詳情請百度 #include <i

資料結構演算法一)Trie字典樹

本文主要包括以下內容: Trie字典樹的基本概念 Trie字典樹的基本操作 插入 查詢 字首查詢 刪除 基於連結串列的Trie字典樹 基於Trie的Set效能對比 LeetCode相關線段樹的問題 LeetCode第208號問題 LeetCode第211

為什麼我要放棄javaScript資料結構演算法(第章)—— 排序和搜尋演算法

本章將會學習最常見的排序和搜尋演算法,如氣泡排序、選擇排序、插入排序、歸併排序、快速排序和堆排序,以及順序排序和二叉搜尋演算法。 第十章 排序和搜尋演算法 排序演算法 我們會從一個最慢的開始,接著是一些效能好一些的方法 先建立一個數組(列表)來表示待排序和搜尋的資料結構。 function Arra

為什麼我要放棄javaScript資料結構演算法(第一章)—— 演算法模式

本章將會學習遞迴、動態規劃和貪心演算法。 第十一章 演算法模式 遞迴 遞迴是一種解決問題的方法,它解決問題的各個小部分,直到解決最初的大問題。遞迴通常涉及函式呼叫自身。 遞迴函式是像下面能夠直接呼叫自身的方式或函式 function recursiveFunction(someParam){

買什麼資料結構演算法,這裡有:動態圖解大經典排序演算法(含JAVA程式碼實現)

上篇的動圖資料結構反響不錯,這次來個動圖排序演算法大全。資料結構與演算法,齊了。 幾張動態圖捋清Java常用資料結構及其設計原理 本文將採取動態圖+文字描述+正確的java程式碼實現來講解以下十大排序演算法: 氣泡排序 選擇排序 插入排序 希爾排序

資料結構演算法】之紅黑樹 --- 第四篇

樹是一種非線性資料結構,這種資料結構要比線性資料結構複雜的多,因此分為三篇部落格進行講解: 第一篇:樹的基本概念及常用操作的Java實現(二叉樹為例) 第二篇:二叉查詢樹 第三篇:紅黑樹 第三篇:紅黑樹 開篇說明:對於紅黑樹的學習,近階段只需要掌握這種資料結構的思想、特點、適

資料結構演算法】之樹的基本概念及常用操作的Java實現(二叉樹為例) --- 第二篇

樹是一種非線性資料結構,這種資料結構要比線性資料結構複雜的多,因此分為三篇部落格進行講解: 第一篇:樹的基本概念及常用操作的Java實現(二叉樹為例) 第二篇:二叉查詢樹 第三篇:紅黑樹 本文目錄: 1、基本概念 1.1  什麼是樹 1.2  樹的

資料結構演算法A》實驗1:按資料元素升序建立單鏈表

** 實驗題目 ** 對輸入的正整數序列建立有序單鏈表。在建立單鏈表的過程中,連結串列中的資料元素按升序排列。當輸入的資料元素在單鏈表中已經存在時,不進行插入操作。 請使用面向物件形式定義結點類和連結串列類,參考程式碼如下。 class Node { int

資料結構演算法A》實驗2:棧的應用

題目: Description 根據棧的特點,實現十進位制到其他進位制之間的轉換,具體要求如下: (1)利用棧進行十進位制數與N進位制(如二進位制、八進位制、十六進位制)資料之間的轉換; (2)通過順序棧記錄進位制轉換的中間結果,該順序棧有一個指示棧頂的變數top,