1. 程式人生 > 其它 >C語言使用遞迴以及非遞迴對二叉樹的先、中和後序遍歷以及層次遍歷

C語言使用遞迴以及非遞迴對二叉樹的先、中和後序遍歷以及層次遍歷

技術標籤:資料結構二叉樹資料結構

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); 

	
	}
}
} 

C++版本的程式碼