考研數據結構之樹(6.1)——二叉樹的遍歷算法(C表示)

二叉樹的主要遍歷方式有先序遍歷、中序遍歷、後序遍歷和層次遍歷。

1.先序遍歷

先序遍歷的操作過程如下:

如果二叉樹爲空樹,則什麼都不做;否則:

(1)訪問根節點

(2)先序遍歷左子樹

(3)先序遍歷右子樹

對應算法代碼如下:

/* 先序遍歷 */
/* *p指的是二叉樹的根節點 */
void preOrder(BTNode *p) {
	if(p!=NULL) {
		printf("%c",p->data);// 打印樹結點的數據 
		preOrder(p->lchild);// 先序遍歷左子樹 
		preOrder(p->rchild);// 先序遍歷右子樹 
	}
}

2.中序遍歷

中序遍歷的操作過程如下:

如果二叉樹爲空樹,則什麼都不做;否則:

(1)中序遍歷左子樹

(2)訪問根節點

(3)中序遍歷右子樹

對應的算法代碼如下:

/* 中序遍歷 */
/* *p指的是二叉樹的根節點 */
void inOrder(BTNode *p) {
	if(p!=NULL) {
		inOrder(p->lchild);
		printf("%c",p->data);
		inOrder(p->rchild);
	}
}

3.中序遍歷

後序遍歷的操作過程如下:

如果二叉樹爲空樹,則什麼都不做;否則:

(1)後序遍歷左子樹

(2)後序遍歷右子樹

(3)訪問根節點

對應的算法代碼如下:

/* 後序遍歷 */
/* *p指的是二叉樹的根節點 */
void postOrder(BTNode *p) {
	if(p!=NULL) {
		postOrder(p->lchild);
		postOrder(p->rchild);
		printf("%c",p->data);
	}
}

完整代碼如下:

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

/* 數結構體類型定義*/
typedef struct BTNode {
	char data;// 這裏默認結點data域爲char類型
	struct BTNode *lchild;// 左孩子指針域
	struct BTNode *rchild;// 右孩子指針域
} BTNode,*BiTree;

/* 根據輸入創建二叉樹 */
/* 例:ABC##DE##F##GH### */
void CreatBiNode(BTNode **Node) { //此處應注意傳遞的參數(二重指針)
	char data;
	scanf("%c", &data);

	*Node = (BiTree)malloc(sizeof(BTNode));
	if (data == '#') {
		*Node = NULL;
	} else if ((data != '#') && (*Node)) {
		(*Node)->data = data;
		(*Node)->lchild = NULL;
		(*Node)->rchild = NULL;
		CreatBiNode(&(*Node)->lchild);
		CreatBiNode(&(*Node)->rchild);
	}
}

/* 先序遍歷 */
/* *p指的是二叉樹的根節點 */
void preOrder(BTNode *p) {
	if(p!=NULL) {
		printf("%c",p->data);// 打印樹結點的數據 
		preOrder(p->lchild);// 先序遍歷左子樹 
		preOrder(p->rchild);// 先序遍歷右子樹 
	}
}

/* 中序遍歷 */
/* *p指的是二叉樹的根節點 */
void inOrder(BTNode *p) {
	if(p!=NULL) {
		inOrder(p->lchild);
		printf("%c",p->data);
		inOrder(p->rchild);
	}
}

/* 後序遍歷 */
/* *p指的是二叉樹的根節點 */
void postOrder(BTNode *p) {
	if(p!=NULL) {
		postOrder(p->lchild);
		postOrder(p->rchild);
		printf("%c",p->data);
	}
}

int main() {
	printf("先序輸入二叉樹(空結點用'#'表示):");
	BiTree T=NULL;
	CreatBiNode(&T);// 創建二叉樹

	/* 先序遍歷 */
	printf("先序遍歷:");
	preOrder(T);

	/* 中序遍歷 */
	printf("\n中序遍歷:");
	inOrder(T);

	/* 後序遍歷 */
	printf("\n後序遍歷:");
	postOrder(T);

	return 0;
}

注意:上面創建的二叉樹使用的是先序遍歷的方式,所以輸入字符的時候要按照先序的方式。

注意:空結點用“#”表示,而輸入一個先序字符串,然後按回車,創建二叉樹完成。

4.層次遍歷

如上圖,先遍歷每一層。第一層是A,第二層是BC,第三層是DEFG,第四層是HI。所以結果爲ABCDEFGHI。

圖6-10所示爲二叉樹的層次遍歷,即按照箭頭所指方向,按照1、2、3、4的層次順序,對二叉樹中各個結點進行訪問(此圖反映的是自左至右的層次遍歷,自右至左的方式類似)。

要進行層次遍歷,需要建立一個循環隊列。先將二叉樹頭結點入隊列,然後出隊列,訪問該結點,如果它有左子樹,則將左子樹的根結點入隊:如果它有右子樹,則將右子樹的根結點入隊。然後出隊列,對出隊結點訪問。如此反覆,直到隊列爲空爲止。

核心代碼:

/* 層次遍歷 */ 
void level(BTNode *p) {
	int front,rear;
	BTNode *que[maxSize];// 定義一個循環隊列,用來記錄要訪問的層次上的結點
	front=rear=0;
	BTNode *q;
	if(p!=NULL) {
		rear=(rear+1)%maxSize;
		que[rear]=p;// 根節點入隊
		while(front!=rear) { // 當隊列不空的時候進行循環
			front=(front+1)%maxSize;
			q=que[front];// 隊頭結點出隊
			printf("%c",q->data);// 訪問隊頭結點
			if(q->lchild!=NULL) { // 如果左子樹不空,則左子樹的根節點入隊
				rear=(rear+1)%maxSize;
				que[rear]=q->lchild;
			}
			if(q->rchild!=NULL) { // 如果右子樹不空,則右子樹的根節點入隊
				rear=(rear+1)%maxSize;
				que[rear]=q->rchild;
			}
		}
	}
}

完整代碼:

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

#define maxSize 30

/* 數結構體類型定義*/
typedef struct BTNode {
	char data;// 這裏默認結點data域爲char類型
	struct BTNode *lchild;// 左孩子指針域
	struct BTNode *rchild;// 右孩子指針域
} BTNode,*BiTree;

/* 根據輸入創建二叉樹 */
/* 例:ABC##DE##F##GH### */
void CreatBiNode(BTNode **Node) { //此處應注意傳遞的參數(二重指針)
	char data;
	scanf("%c", &data);

	*Node = (BiTree)malloc(sizeof(BTNode));
	if (data == '#') {
		*Node = NULL;
	} else if ((data != '#') && (*Node)) {
		(*Node)->data = data;
		(*Node)->lchild = NULL;
		(*Node)->rchild = NULL;
		CreatBiNode(&(*Node)->lchild);
		CreatBiNode(&(*Node)->rchild);
	}
}

/* 層次遍歷 */ 
void level(BTNode *p) {
	int front,rear;
	BTNode *que[maxSize];// 定義一個循環隊列,用來記錄要訪問的層次上的結點
	front=rear=0;
	BTNode *q;
	if(p!=NULL) {
		rear=(rear+1)%maxSize;
		que[rear]=p;// 根節點入隊
		while(front!=rear) { // 當隊列不空的時候進行循環
			front=(front+1)%maxSize;
			q=que[front];// 隊頭結點出隊
			printf("%c",q->data);// 訪問隊頭結點
			if(q->lchild!=NULL) { // 如果左子樹不空,則左子樹的根節點入隊
				rear=(rear+1)%maxSize;
				que[rear]=q->lchild;
			}
			if(q->rchild!=NULL) { // 如果右子樹不空,則右子樹的根節點入隊
				rear=(rear+1)%maxSize;
				que[rear]=q->rchild;
			}
		}
	}
}

int main() {
	printf("先序輸入二叉樹(空結點用'#'表示):");
	BiTree T=NULL;
	CreatBiNode(&T);// 創建二叉樹

	/* 層次遍歷 */ 
	printf("層次遍歷:");
	level(T);

	return 0;
}

運行結果:

以下圖爲例輸入(其中空結點用“#”表示),輸入的字符串如下:

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章