这里先提一句为什么之前树的创建可以由前序遍历的方法搞定,原因是前序遍历的时候把所有的空节点都包含在内了,如果仅仅只有非空节点的前序遍历输入,是无法得到单一二叉树的,例如给出了一个前序遍历顺序AB
那么有可能是两种情况,如下图所示
A 或者 A
B B
甚至给出它的后序遍历也不可以,如果得知两种遍历顺序希望获得唯一的二叉树,至少要给出其中序遍历
转回主题,如何利用队列实现层序遍历呢
队列实现:遍历从根节点开始,首先将根节点入队,然后开始执行循环:结点出队、访问该节点、其左右儿子入队
层序遍历的基本过程是:
先根节点入队,然后:
1.从队列中取出一个元素
2.访问该元素所指的结点
3.若该元素所指结点的左、右孩子结点非空,则将其左、右孩子的指针顺序入队
实现代码如下
#include "stdio.h"
#include "stdlib.h"
#define ERROR 0
typedef struct tree
{
char data;
struct tree *lchild;
struct tree *rchild;
}*Ptree;
typedef Ptree ElementType;
struct Node{
ElementType Data;
struct Node *Next;
};
struct QNode{
struct Node *rear;
struct Node *front;
};
typedef struct QNode *Queue;
//创建树
Ptree createTree();
//创建队列
Queue CreateQueue();
//删除队列头元素
ElementType DeleteQ(Queue PtrQ);
//在队尾插入元素
void InsertQ(ElementType item,Queue PtrQ);
//判断是否空
int IsEmpty(Queue Q);
//利用队列层次遍历
void LevelOrderTraversal(Ptree BT);
void main()
{
Ptree t;
printf("先序创建二叉树,用空格代表虚结点:\n");
t=createTree();
printf("\n");
printf("利用队列的层次遍历:\n");
LevelOrderTraversal(t);
printf("\n");
system("pause");
}
//树的建立
Ptree createTree()
{
char ch;
Ptree t;
ch=getchar(); //输入二叉树数据
if(ch==' ') //判断二叉树是否为空
t=NULL;
else
{
t=(Ptree)malloc(sizeof(Ptree)); //二叉树的生成
t->data=ch;
t->lchild=createTree();
t->rchild=createTree();
}
return t;
}
//创建队列
Queue CreateQueue(){
Queue PtrQ;
PtrQ=(Queue)malloc(sizeof(struct QNode));
struct Node *rear;
struct Node *front;
rear =(Node*)malloc(sizeof(struct Node));
rear=NULL;
front =(Node*)malloc(sizeof(struct Node));
front=NULL;
PtrQ->front=front;
PtrQ->rear=rear;
return PtrQ;
};
//删除队列头元素
ElementType DeleteQ(Queue PtrQ){
struct Node *FrontCell;
ElementType FrontElem;
if(IsEmpty(PtrQ)){
printf("队列空");
return ERROR;
}
FrontCell=PtrQ->front;
if(PtrQ->front==PtrQ->rear)
PtrQ->front=PtrQ->rear=NULL;
else{
PtrQ->front=PtrQ->front->Next;
}
FrontElem=FrontCell->Data;
free(FrontCell);
return FrontElem;
}
//在队尾插入元素
void InsertQ(ElementType item,Queue PtrQ){
struct Node *FrontCell;
FrontCell=(Node*)malloc(sizeof(struct Node));
FrontCell->Data=item;
FrontCell->Next=NULL;
if(IsEmpty(PtrQ)){
PtrQ->front=FrontCell;
PtrQ->rear=FrontCell;
}
else{
PtrQ->rear->Next=FrontCell;
PtrQ->rear=FrontCell;
}
};
//判断是否空
int IsEmpty(Queue Q){
return(Q->front==NULL);
};
//利用队列层次遍历
void LevelOrderTraversal(Ptree BT)
{
Queue Q;
Ptree T;
if(!BT) return;
Q=CreateQueue();
T=BT;
InsertQ(T,Q);
while(!IsEmpty(Q)){
T=DeleteQ(Q);
printf("%c",T->data);
if(T->lchild) InsertQ(T->lchild,Q);
if(T->rchild) InsertQ(T->rchild,Q);
}
};
二叉树和之前的一样
A
B C
D F G I
E H