树的层序遍历
树的先序,中序,后序遍历对应了深度优先遍历。而层序遍历为广度优先遍历。
层序遍历很好理解,从根节开始一层层的遍历访问,访问完第一层访问第二层。
定义一个队列就可以搞定层序遍历了。
还是这个例子,这个树的层序遍历序列为:1 2 3 4 5 6
代码实现
//层序遍历
void LevelOrder(LinkQueue Q,BiTree T){
BiTree p;
EnQueue(Q,T);//将根节点入队
while(!isEmptyQueue(Q)){//队列不空,循环
DeQueue(Q,p);//出队列
printf("%c ",p->data);//访问
if(p->lchild) EnQueue(Q,p->lchild);//如果有左孩子将左孩子入队
if(p->rchild) EnQueue(Q,p->rchild);//如果有右孩子将右孩子入队
}
}
完整代码
#include<stdio.h>
#include<stdlib.h>
//定义树节点
typedef struct BiNode{
char data;//数据域
struct BiNode *lchild,*rchild;//指针域,分别指向左孩子和右孩子
}BiTNode,*BiTree;
//队列节点的结构定义
typedef struct Linknode{
BiTree data;
struct Linknode *next;
}Linknode;
//队列首尾指针的定义
typedef struct{
Linknode *front,*rear;
}LinkQueue;
//创建一棵树,先序创建
void CreateTree(BiTree &T){
char ch;//存放输入值
scanf("%c\n",&ch);
if(ch=='#')
T=NULL;
else
{
T=(BiTree)malloc(sizeof(BiNode));
T->data=ch;
CreateTree(T->lchild);
CreateTree(T->rchild);
}
}
//初始化队列
void InitQueue(LinkQueue &Q){
//带头结点的链队列
Q.front=(Linknode*)malloc(sizeof(Linknode));
Q.rear=Q.front;
Q.front->next=NULL;
}
//入队
void EnQueue(LinkQueue &Q,BiTree p){
//S指向新节点,连接Q.rear后面
Linknode *S=(Linknode*)malloc(sizeof(Linknode));
S->data=p;
S->next=NULL;
Q.rear->next=S;
Q.rear=S;
}
//出队
bool DeQueue(LinkQueue &Q,BiTree &p){
//如果队空就不能出队列了
if(Q.front==Q.rear) return false;
Linknode *q=Q.front->next;
p=q->data;
Q.front->next=q->next;
//刚好最后一个结点出队了,把rear指向头结点从而判空
if(q==Q.rear){
Q.rear=Q.front;
}
free(q);
return true;
}
//判空
bool isEmptyQueue(LinkQueue Q){
if(Q.front==Q.rear) return true;
else return false;
}
//层序遍历
void LevelOrder(LinkQueue Q,BiTree T){
BiTree p;
EnQueue(Q,T);
while(!isEmptyQueue(Q)){
DeQueue(Q,p);
printf("%c ",p->data);
if(p->lchild) EnQueue(Q,p->lchild);
if(p->rchild) EnQueue(Q,p->rchild);
}
}
int main(){
BiTree T;
CreateTree(T);
LinkQueue Q;
InitQueue(Q);
printf("树的层序遍历:");
LevelOrder(Q,T);
return 0;
}
结果展示
第五章就实现到这里吧!