二叉樹遍歷的遞歸實現詳解(先序、中序、后序和層次遍歷)


由二叉樹的定義可知,一棵二叉樹由根結點、左子樹和右子樹三部分組成。因此,只要遍歷了這三個部分,就可以實現遍歷整個二叉樹。若以D、L、R分別表示遍歷根結點、左子樹、右子樹,則二叉樹的遞歸遍歷可以有一下四種方式:

先序遍歷(DLR)

先序遍歷的遞歸過程為

(1)訪問根結點
(2)先序遍歷根結點的左子樹
(3)先序遍歷根結點的右子樹

舉例:

代碼:

void PreOrder(BiTree bt)
{
    if(bt ==NULL)return;    //遞歸的結束條件----某結點為空時
    printf("%d",bt->data);      //這里用printf data表示訪問結點的數據域
    PreOrder(bt->lchild);   //遞歸遍歷左孩子
    PreOrder(bt->rclild);   //遞歸遍歷右孩子
}

中序遍歷(LDR

(1)中序遍歷根結點的左子樹
(2)訪問根結點
(3)中序遍歷根結點的右子樹

舉例:

代碼:

void InOrder(BiTree bt)
{
    if(bt ==NULL)return;    //遞歸的結束條件----某結點為空時
    InOrder(bt->lchild);   //遞歸遍歷左孩子
    printf("%d",bt->data);      //這里用printf data表示訪問結點的數據域
    InOrder(bt->rclild);   //遞歸遍歷右孩子
}

后序遍歷(LRD)

(1)后序遍歷二叉樹的左子樹
(2)后序遍歷二叉樹的右子樹
(3)訪問根結點。

舉例:

代碼:

void PostOrder(BiTree bt)
{
    if(bt ==NULL)return;    //遞歸的結束條件----某結點為空時
    PostOrder(bt->lchild);   //遞歸遍歷左孩子
    PostOrder(bt->rclild);   //遞歸遍歷右孩子
    printf("%d",bt->data);      //這里用printf data表示訪問結點的數據域
}     

層次遍歷

(1)根結點入隊列
(2)根結點出隊列,根結點的左子樹、右子樹相繼入隊列
(3)根結點的左子樹結點出隊列,左子樹結點的左子樹、右子樹相繼入隊列
(4).......

舉例:

代碼:

//層次遍歷二叉樹
void LevelOrder(BiTree T)
{
	BiTree Queue[MAX],b;        //用一維數組表示隊列,front和rear表示隊首和隊尾的指針
	int front,rear;
	front=rear=0;
	if(T)
	//若樹為空    
	{
		Queue[rear++]=T;    //根節點入隊列
		while(front!=rear)  //當隊列非空
		{
			b=Queue[front++];     //隊首元素出隊列,並訪問這個節點 
			printf("%2c",b->data);
			if(b->lchild!=NULL) Queue[rear++]=b->lchild ;  //若左子樹非空,則入隊列
			if(b->rchild!=NULL) Queue[rear++]=b->rchild ;  //若右子樹非空,則入隊列 
		} 
	}	
} 

最終代碼:

#include<stdio.h>
#include<stdlib.h>
#define MAX 20
typedef char TElemType;
typedef int Status;
typedef struct BiTNode
{
	TElemType data;   
	struct BiTNode *lchild,*rchild;	//左右孩子的指針 
} BiTNode,*BiTree;
//先序創建二叉樹
void CreateBiTree(BiTree *T)
{
	char ch;
	ch=getchar();
	if(ch=='#')(*T)=NULL;   //#代表空指針
	else
	{
		(*T)=(BiTree)malloc(sizeof(BiTNode));  //申請節點
		(*T)->data=ch;	    //生成跟節點
		CreateBiTree(&(*T)->lchild);
		CreateBiTree(&(*T)->rchild);
	}	
} 
//先序輸出二叉樹
void PreOrder(BiTree T)
{
	if(T)
	{
		printf("%2c",T->data);   //訪問根節點,此處為輸出根節點的數據值	
		PreOrder(T->lchild);     //先序遍歷左子樹
		PreOrder(T->rchild);     //先序遍歷右子樹
	} 
} 
//中序輸出二叉樹
void InOrder(BiTree T)
{
if(T)
	{
		InOrder(T->lchild);
		printf("%2c",T->data);
		InOrder(T->rchild);
	}	
} 
//后序輸出二叉樹
void PostOrder(BiTree T)
{
if(T)
	{
		PostOrder(T->lchild);
		PostOrder(T->rchild);
		printf("%2c",T->data);
	}	
} 
//層次遍歷二叉樹
void LevelOrder(BiTree T)
{
	BiTree Queue[MAX],b;        //用一維數組表示隊列,front和rear表示隊首和隊尾的指針
	int front,rear;
	front=rear=0;
	if(T)
	//若樹為空    
	{
		Queue[rear++]=T;    //根節點入隊列
		while(front!=rear)  //當隊列非空
		{
			b=Queue[front++];     //隊首元素出隊列,並訪問這個節點 
			printf("%2c",b->data);
			if(b->lchild!=NULL) Queue[rear++]=b->lchild ;  //若左子樹非空,則入隊列
			if(b->rchild!=NULL) Queue[rear++]=b->rchild ;  //若右子樹非空,則入隊列 
		} 
	}	
} 
//求樹的深度
int depth(BiTree T)
{
	int dep1,dep2;
	if(T==NULL) return 0;
	else
	{
		dep1=depth(T->lchild);
		dep2=depth(T->rchild);
		return dep1>dep2?dep1+1:dep2+1;	
	}	
} 
int main()
{
	BiTree T=NULL;
	printf("\n 創建一棵二叉樹: \n");
	CreateBiTree(&T);  //創建二叉樹
	printf("\n先序遍歷的結果為:\n");
	PreOrder(T);  //先序遍歷
	printf("\n中序遍歷的結果為:\n");
	InOrder(T);  //中序遍歷 
	printf("\n 后序遍歷的結果為: \n");
	PostOrder(T); 
	printf("\n 層次遍歷的結果為: \n");
	LevelOrder(T); //層次遍歷
	printf("\n 樹的深度為:%d\n",depth(T)); 
}

結果示例:

大家喜歡的話可以點個贊,有錯誤的地方請務必在評論區指出喲


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM