1. 程式人生 > >二叉樹-連結串列儲存結構及其簡單演算法

二叉樹-連結串列儲存結構及其簡單演算法

適用於層次結構的資料(大部分演算法用遞迴思想)

#include <stdio.h>
#define Max 100
結構體
typedef struct TNode{
	int data;
	struct Node * lchild;//左孩子結點
	struct Node * rchild;//右孩子節點
}TNode; 
//先序遍歷(/根結點->左孩子->右孩子)
void preTrave(TNode* node){
	if(node!=NULL){
			printf("%d",node->data);
			preTrave(node->lchild);
			preTrave(node->rchild);
	}
}
//中序遍歷(左孩子->根結點->右孩子)
void midTrave(TNode* node){
	if(node!=NULL){
		midTrave(node->lchild);
		printf("%d",node->data);
		midTrave(node->rchild);
	}
}
//後序遍歷(左孩子->右孩子->根結點)
void lateTrave(TNode * node){
	if(node!=NULL){
		lateTrave(node->lchild);
		lateTrave(node->rchild);
		printf("%d",node->data;)
	}
}
//層序遍歷(利用順序(迴圈)佇列的特性)
void cTrave(TNode *node){
		TNode * que[Max];//存放樹結點
		int front,rear;
		front = rear = 0;//佇列初始化
		TNode * s;
		if(node!=NULL){
			rear = (rear + 1)%Max;
			que[rear] = node;//根結點入隊
			while(rear != front){//如果隊不空
				front = (front+1) %Max;
				s = que[front];//根結點出隊
				print("%d",s->data);
				if(s->lchild!=NULL){//如果左孩子不為空
					rear = (rear + 1)%Max;
					que[rear] = s->lchild;//左孩子結點入隊
				}
				if(s->rchild!=NULL){//如果右孩子不為空
					rear = (rear +1)%Max;
					que[rear] = s->rchild;//右孩子入隊
				}
			}
		}
}

//求寬度(利用順序非迴圈的佇列,增加一個結構體來儲存結點指標以及結點所在的層次號)
typedef struct T{
	TNode * node;//結點指標
	int no;//結點所在層次號
}
int getWidth(TNode * node){
	T que[Max];
	int front,rear;//定義一個順序非迴圈佇列
	front = rear = 0;
	int i,j,n,max,Lno;
	TNode s;
	if(node!=NULL){
		++rear;
		que[rear].node = node;//根結點入隊
		que[rear].no = 1;//根結點所在層次為1
		while(front!=rear){//如果隊不空
			++front;
			s = que[front].node;//結點出隊
			Lno = que[front].no;//關鍵一步:儲存當前結點的層次號
			if(s->lchild!=NULL){//左孩子不空則將左孩子入隊
				++rear;
				que[rear].node = s->lchild;
				que[rear].no = Lno+!;//關鍵一步:根據當前結點層次號計算其孩子結點層次號
			}
			if(s->rchild!=NULL){//如果右孩子不為空則將右孩子入隊
				++rear;
				que[rear].node = s->rchild;
				que[rear].no = Lno+!;//關鍵一步:根據當前結點層次號計算其孩子結點層次號
			}
		}//迴圈結束,Lno中儲存了這棵二叉樹中最大的層數
		//以下程式碼找出含有結點最多的層中的結點數
		max = 0;
		for(i=0;i<=Lno;i++){
			n = 0;
			for(j=1;j<=rear;j++){
				if(que[j].no==i){
					++n;
				}
			}
			if(max<n){
				max = n;
			}
		}
		return max;
	}else{
		return 0;//空樹直接返回0
	}
}

//求二叉樹深度(遞迴)
int getDepth(TNode * node){
	int ld;rd;//用於接收左右深度
	if(node!=NULL){
		ld = getDepth(node->lchild);
		rd = getDepth(node->rchild);
		return (ld>rd?ld:rd)+1'
	}else{
		return 0;
	}
}
//求值為key的結點在二叉樹中的位置
void getNo(TNode * root,int key,TNode ** node){
	if(root!=NULL){
		if(root->data == key){
			(*node) = root;
		}else{
			getNo(root->lchild,key,node);
			if(node!=NULL){
				getNO(root->rchild,key,node);
			}
		}
	}
}
//二叉樹的創立(遞迴)
TNode * init(){
	int data;
	scanf("%d",&data);
	TNode * node = NULL;
	if(data!=-1){
		node = (TNode*)malloc(sizeof(TNode));
		node->data = data;//給樹節點賦值
		root->lchild = init();//建立左孩子
		root->rchild = init();//建立右孩子
	}
	return node;
}
//二叉樹的銷燬(後序遍歷思想)
void destory(TNode * node){
	if(node!=NULL){
		destory(node->lchild);
		destory(node->rchild);
		free(node);//釋放結點
	}
}
//二叉排序樹的插入(左孩子小右孩子大)
void insertNode(TNode ** node,int key){
	if(node!=NULL){//結點是否為空;不為空的比較大小插入
		if(key<(*node)->data){//比根結點小則在左邊
			insertNode((*root)->lchild,key);
		}else{//比根結點大或者相等則在右邊
			insetNode((*node)->rchild,key);
		}
	}else{//為空則新建結點
		(*root) = (TNode*)malloc(sizeof(TNode));
		(*root)->data =key;
	}
}
//在二叉排序樹中查詢某個結點
TNode * findNode(TNode * node,int key){
	if(node!=NULL){
		if(key==node->data){
			return node;
		}else if(key<node->data){
			findNode(node->lchild,key);
		}else{
			findNode(node->rchild,key);
		}
	}else{
		return NULL;
	}
}

//表示式(a-(b+c))*(d/e),編寫程式求出該表示式的值(使用後序遍歷)