由二叉樹的定義可知,一棵二叉樹由根結點、左子樹和右子樹三部分組成。因此,只要遍歷了這三個部分,就可以實現遍歷整個二叉樹。若以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));
}
結果示例:
大家喜歡的話可以點個贊,有錯誤的地方請務必在評論區指出喲