1. 程式人生 > >二叉樹建立、先序遍歷、中序遍歷、後序遍歷、樹深度

二叉樹建立、先序遍歷、中序遍歷、後序遍歷、樹深度

一、概念:

        二叉樹遍歷:按指定的某條搜尋路徑訪問樹中每個結點,使得每個結點均被訪問一次,而且僅被訪問一次。

        根節點N,按照先遍歷左子樹L再遍歷右子樹R的原則,常見的有三種:先序(NLR)、中序(LNR)、後序(LRN)。其中,序是指根節點什麼時候被訪問。

有時還有提到層序(按層遍歷訪問)

        例如:下圖


           顯然 深度為 4

           求先序遍歷:    A(以A為根的左子樹)(以A為根的右子樹)——A(B)(以C為根的先序遍歷)——ABC(E、F、G)——A B C D E F G

              同理中序:中間訪問根節點:B A D C F E G

              後序遍歷:B D F G E C A

二、演算法實現

       先序遍歷操作過程:(遞迴)

                   如果二叉樹為空,什麼也不做。

                   否則:

                   (1)訪問根節點

                   (2)先序遍歷左子樹

                   (3)先序遍歷右子樹

                    遞迴注意結束條件

    

               //先序遍歷遞迴
int PreOrder(BiTree T){
	if(T!=NULL){
		Visit(T);
		PreOrder(T->lchild);
		PreOrder(T->rchild);
	}
	return 0;
}

         中序遍歷操作過程:(遞迴)

                   如果二叉樹為空,什麼也不做。

                   否則:

                   (1)中序遍歷左子樹

                   (2)訪問根節點

                   (3)中序遍歷右子樹

                    遞迴注意結束條件

//中序遍歷遞迴
int InOrder(BiTree T){
	if(T!=NULL){		
		InOrder(T->lchild);
		Visit(T);
		InOrder(T->rchild);
	}
	return 0;
}

       後序遍歷操作過程:(遞迴)

                   如果二叉樹為空,什麼也不做。

                   否則:

                   (1)後序遍歷左子樹

                   (2)後序遍歷右子樹

                   (3)訪問根節點

                    遞迴注意結束條件

//後序遍歷遞迴
int PostOrder(BiTree T){
	if(T!=NULL){		
		PostOrder(T->lchild);		
		PostOrder(T->rchild);
		Visit(T);
	}
	return 0;
}


                三種時間複雜度O(n)

                 最壞情況下,n個結點深度為n的斜樹

                 層序遍歷(  使用佇列)

                 完整程式碼:

#include<stdio.h>
#include<stdlib.h>

typedef char ElemType;//結點資料型別

//二叉樹結點
typedef struct BiTNode{
	ElemType data;//資料
	struct BiTNode *lchild; //左子樹指標
	struct BiTNode *rchild; //右子樹指標
}BiTNode,*BiTree;

//先序輸入建立二叉樹
int CreatBiTre(BiTree &T){
	ElemType x;//輸入結點值
	scanf("%c",&x);
	if(x=='#') T=NULL;//空結點輸入空格
	else{
		T=(BiTree)malloc(sizeof(BiTNode));
		if(T==NULL){
			printf("OVERFLOW!\n");
			exit(1);			
		}
		T->data=x;
		CreatBiTre(T->lchild);
		CreatBiTre(T->rchild);		
	}
	return 0;
}
void Visit(BiTree T){
	if(T->data!='#')
		printf("%c ",T->data);	
}

//先序遍歷遞迴
int PreOrder(BiTree T){
	if(T!=NULL){
		Visit(T);
		PreOrder(T->lchild);
		PreOrder(T->rchild);
	}
	return 0;
}

//中序遍歷遞迴
int InOrder(BiTree T){
	if(T!=NULL){		
		InOrder(T->lchild);
		Visit(T);
		InOrder(T->rchild);
	}
	return 0;
}

//後序遍歷遞迴
int PostOrder(BiTree T){
	if(T!=NULL){		
		PostOrder(T->lchild);		
		PostOrder(T->rchild);
		Visit(T);
	}
	return 0;
}

//樹的深度遞迴
int TreeHeight(BiTree T){
	int height,left,right;
	if(T==NULL)		
		return 0;	
	left=TreeHeight(T->lchild);
	right=TreeHeight(T->rchild);
	height=(left>right)?left:right;
	return height+1;	//算上根結點一層
}

void main(){
	BiTree T=NULL;
	CreatBiTre(T);
	int height;
	height=TreeHeight(T);
	printf("樹的深度: %d\n",height);

	printf("先序遍歷: ");
	PreOrder(T);
	printf("\n");

	printf("中序遍歷: ");
	InOrder(T);
	printf("\n");

	printf("後序遍歷: ");
	PostOrder(T);
	printf("\n");
}

        截圖: