考研数据结构之树(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;
}

运行结果:

以下图为例输入(其中空结点用“#”表示),输入的字符串如下:

 

 

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