C語言使用遞迴以及非遞迴對二叉樹的先、中和後序遍歷以及層次遍歷
阿新 • • 發佈:2020-12-20
C語言通過遞迴和非遞迴 對二叉樹的先序、中序、後序以及層次遍歷
資料型別定義
typedef char TElemType;
typedef int Status;
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
二叉樹建立
Status 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) ;
//構造右子樹
}
return 1;
}
輸入方式:ABC##DE#G##F###
按先序次序輸入二叉樹中結點的值,用‘#’表示空樹,對每一個結點應當確定其左右子樹的值(為空時必須用特定的空字元佔位)
建立如圖的二叉樹
先序遍歷
遞迴
void PreOrder(BiTree T) {
if (T) {
printf("%2c",T->data);
//訪問根結點,此處簡化為輸出根結點的資料值
PreOrder(T->lchild);
//先序遍歷左子樹
PreOrder(T->rchild);
//先序遍歷右子樹
}
}
非遞迴
void Norec_PreOrder(BiTree T) {
if (T) {
BiTree stack[10];
int stackTop = -1;
BiTree t = T;
while (stackTop != -1 || t) {
while(t) {
printf(" %c", t->data);
stack[++stackTop] = t;
t = t->lchild;
}
if(stackTop != -1) {
t = stack[stackTop--];
t = t->rchild;
}
}
}
}
中序遍歷
遞迴
void InOrder(BiTree T) {
if (T) {
InOrder(T->lchild);
//先序遍歷左子樹
printf("%2c",T->data);
//訪問根結點,此處簡化為輸出根結點的資料值
InOrder(T->rchild);
//先序遍歷右子樹
}
}
非遞迴
void Norec_InOrder(BiTree T) {
if (T) {
BiTree stack[10];
int stackTop = -1;
BiTree t = T;
while(stackTop != -1 || t) {
while(t) {
stack[++stackTop] = t;
t = t->lchild;
}
if(stackTop != -1) {
t = stack[stackTop--];
printf(" %c", t->data);
t = t->rchild;
}
}
}
}
後序遍歷
遞迴
void PostOrder(BiTree T) {
if (T) {
PostOrder(T->lchild);
//先序遍歷左子樹
PostOrder(T->rchild);
//先序遍歷右子樹
printf("%2c",T->data);
//訪問根結點,此處簡化為輸出根結點的資料值
}
}
非遞迴
void Norec_PostOrder(BiTree T) {
if (T) {
BiTree stack[10];
int stackTop = -1;
BiTree t = T;
BiTree tem = Null;
while(stackTop != -1 || t) {
if(t) {
stack[++stackTop] = t;
t = t->lchild;
// printf("stackTop : %d , value:%c",stackTop,t->data);
} else {
t = stack[stackTop];
if(t->rchild&&t->rchild!=tem) {
t = t->rchild;
} else {
stackTop--;
printf(" %c", t->data);
tem = t;
t = Null;
}
}
}
}
}
層次遍歷
void LevleOrder(BiTree T) {
//層次遍歷二叉樹T,從第一層開始,每層從左到右
BiTree Queue[MAX],b;
//用一維陣列表示佇列
int front,rear;
// 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;
}
}
}
//LevelOrder
求二叉樹的深度
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;
}
}
//depth
完整程式碼
#include "stdio.h"
#include "stdlib.h"
#include<stdlib.h>
#define MAX 20
#define Null 0
typedef char TElemType;
typedef int Status;
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
Status 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) ;
//構造右子樹
}
return 1;
}
// 遞迴 先序遍歷
void PreOrder(BiTree T) {
if (T) {
printf("%2c",T->data);
//訪問根結點,此處簡化為輸出根結點的資料值
PreOrder(T->lchild);
//先序遍歷左子樹
PreOrder(T->rchild);
//先序遍歷右子樹
}
}
void Norec_PreOrder(BiTree T) {
if (T) {
BiTree stack[10];
int stackTop = -1;
BiTree t = T;
while(stackTop != -1 || t) {
while(t) {
printf(" %c", t->data);
stack[++stackTop] = t;
t = t->lchild;
}
if(stackTop != -1) {
t = stack[stackTop--];
t = t->rchild;
}
}
}
}
// 遞迴 中序遍歷
void InOrder(BiTree T) {
if (T) {
InOrder(T->lchild);
//先序遍歷左子樹
printf("%2c",T->data);
//訪問根結點,此處簡化為輸出根結點的資料值
InOrder(T->rchild);
//先序遍歷右子樹
}
}
void Norec_InOrder(BiTree T) {
if (T) {
BiTree stack[10];
int stackTop = -1;
BiTree t = T;
while(stackTop != -1 || t) {
while(t) {
stack[++stackTop] = t;
t = t->lchild;
}
if(stackTop != -1) {
t = stack[stackTop--];
printf(" %c", t->data);
t = t->rchild;
}
}
}
}
void PostOrder(BiTree T) {
if (T) {
PostOrder(T->lchild);
//先序遍歷左子樹
PostOrder(T->rchild);
//先序遍歷右子樹
printf("%2c",T->data);
//訪問根結點,此處簡化為輸出根結點的資料值
}
}
void Norec_PostOrder(BiTree T) {
if (T) {
BiTree stack[10];
int stackTop = -1;
BiTree t = T;
BiTree tem = Null;
while(stackTop != -1 || t) {
if(t) {
stack[++stackTop] = t;
t = t->lchild;
// printf("stackTop : %d , value:%c",stackTop,t->data);
} else {
t = stack[stackTop];
if(t->rchild&&t->rchild!=tem) {
t = t->rchild;
} else {
stackTop--;
printf(" %c", t->data);
tem = t;
t = Null;
}
}
}
}
}
void LevleOrder(BiTree T) {
//層次遍歷二叉樹T,從第一層開始,每層從左到右
BiTree Queue[MAX],b;
//用一維陣列表示佇列
int front,rear;
// 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;
}
}
}
//LevelOrder
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;
}
}
//depth
void main() {
printf("-----------------------------\n");
BiTree T=Null;
printf("\n請輸入一顆二叉樹~:\n");
CreateBiTree(&T);
printf("\n一顆二叉樹建立完成~:\n");
printf("\n");
while(1) {
printf("\n-----------------------------\n");
int num;
printf("請輸入序號1-8:\n");
printf("1. 先序非遞迴遍歷\n");
printf("2. 先序遞迴遍歷\n");
printf("3. 中序非遞迴遍歷\n");
printf("4. 中序遞迴遍歷\n");
printf("5. 後序非遞迴遍歷\n");
printf("6. 後序遞迴遍歷\n");
printf("7. 層次遍歷\n");
printf("8. 樹的深度\n");
printf("9. 退出\n");
printf("\n-----------------------------\n");
scanf("%d",&num);
switch(num) {
case 1:printf("\n先序非遞迴遍歷結果為:\n");Norec_PreOrder(T);printf("\n");break;
case 2:printf("\n先序遞迴遍歷結果為:\n");PreOrder(T);printf("\n");break;
case 3:printf("\n中序非遞迴遍歷結果為:\n");Norec_InOrder(T);printf("\n");break;
case 4:printf("\n中序遞迴遍歷結果為:\n");InOrder(T);printf("\n");break;
case 5:printf("\n後序非遞迴遍歷結果為:\n");Norec_PostOrder(T);printf("\n");break;
case 6:printf("\n後序遞迴遍歷結果為:\n");PostOrder(T);printf("\n");break;
case 7:printf("\n層次遍歷的結果為:\n");LevleOrder(T);printf("\n");break;
case 8:printf("\n數的深度為:%d\n",depth(T));printf("\n");break;
case 9:printf("\n886\n");exit(0);
}
}
}