★算法思想★
- 初始化一个辅助队列
- 根结点入队
- 若队列非空,则队头结点出队,访问该结点,并将其左、右孩子插入队尾(如果有的话)
- 重复3中的操作直至队列为空
- PS:从上述算法思想中可以看出需要用到的队列相关操作有:初始化队列、判空、入队、出队。
1.头文件及元素类型定义
#include<stdio.h>
#include<stdlib.h>
#define ElemType BiTNode*
#define ElemType1 char
2.相关类型定义
typedef struct BiTNode {
ElemType1 data;
struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;
typedef struct LinkNode {
BiTNode* data;
struct LinkNode* next;
}LinkNode;
typedef struct {
LinkNode* front, * rear;
}LinkQueue;
3.函数声明
void InitQueue(LinkQueue& Q);
bool LiQueueEmpty(LinkQueue Q);
bool EnQueue(LinkQueue& Q, ElemType x);
bool ExQueue(LinkQueue& Q, ElemType& x);
void CreateBiTree(BiTree& T);
void visit(BiTNode* p);
void LevelOrder(BiTree T);
4.基本操作
4.1 初始化队列
void InitQueue(LinkQueue& Q) {
Q.front = Q.rear = NULL;
}
4.2 判空
bool LiQueueEmpty(LinkQueue Q) {
return (Q.front == NULL);
}
4.3 入队操作
bool EnQueue(LinkQueue& Q, ElemType x) {
LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
if (s == NULL)
return false;
s->data = x;
s->next = NULL;
if (Q.rear == NULL)
Q.front = Q.rear = s;
else {
Q.rear->next = s;
Q.rear = s;
}
return true;
}
4.4 出队操作
bool ExQueue(LinkQueue& Q, ElemType& x) {
if (Q.front == NULL)
return false;
LinkNode* p = Q.front;
x = p->data;
Q.front = p->next;
if (Q.rear == p)
Q.rear = Q.front = NULL;
free(p);
return true;
}
4.5 先序建立二叉树
void CreateBiTree(BiTree& T) {
char c;
scanf("%c", &c);
if (c == '#')
T = NULL;
else {
T = (BiTNode*)malloc(sizeof(BiTNode));
T->data = c;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
4.6 打印结点
void visit(BiTNode* p) {
printf("%c\t", p->data);
}
4.7 二叉树的层次遍历
void LevelOrder(BiTree T) {
LinkQueue Q;
InitQueue(Q);
BiTree p;
EnQueue(Q, T);
while (!LiQueueEmpty(Q)) {
ExQueue(Q, p);
visit(p);
if (p->lchild != NULL)
EnQueue(Q, p->lchild);
if (p->rchild != NULL)
EnQueue(Q, p->rchild);
}
}
4.8 main函数
int main() {
BiTree T;
printf("先序创建二叉树:");
CreateBiTree(T);
printf("层次遍历二叉树:");
LevelOrder(T);
return 0;
}
4.9 测试
4.9.1 二叉树结构

4.9.2 测试结果

5.小结
- 二叉树的层次遍历与其他三种遍历有所不同,属于广度优先遍历,是队列的具体应用,并且此实现过程是非递归的。
- 至此,二叉树的遍历操作基本介绍完成。遍历是二叉树的各种操作的基础,可以在遍历的过程中对结点进行各种操作,例如:求结点的双亲、求结点的孩子结点等。所有的这些操作都建立在二叉树遍历的基础上,因此,必须掌握二叉树的各种遍历过程,才能更灵活的解决各种问题。
- 遍历二叉树后会得到一个线性序列,除第一个结点和最后一个结点外,每个结点都有一个直接前驱和直接后继。但传统的二叉链表仅能体现父子关系,查找结点的前驱和后继是很不方便的。因此,利用“n个结点的二叉链表中,含有n+1个空链域”这一特性,通过这n+1个空指针来存放其前驱或后继的指针,以达到加快查找结点前驱和后继的速度,因此,引入线索二叉树。