分层遍历二叉树的思想特别简单
1、遍历根节点
2、若根节点的左孩子和右孩子不空,则遍历左孩子和右孩子(从左到右的遍历,如果为从右到左的遍历,只需将遍历左右孩子的顺序颠倒即可)
3、重复以上过程知道二叉树中所有的结点均遍历完为止
二叉树的分层遍历可以使用队列来完成,在队列中保存指向二叉树结点的指针比直接保存二叉树结点的数据简单的多。思想为:
1、指向二叉树根节点的指针入队
2、若队不为空,则队头元素出队,访问出队的指针的数据
3、若出队指针的左孩子不为空,左孩子指针入队
4、若出队指针的右孩子不为空,则右孩子指针入队
5、重复2~4过程知道二叉树的所有结点都遍历完
以上分层遍历二叉树时在遍历每层的结点时为从左到右依次输出,如果想从右到左依次输出,只要颠倒3、4两步即可。
完整代码如下
#include<iostream>
#define OK 1;
#define ERROR -1;
typedef char VertexType;
typedef struct BinNode{
VertexType data;
BinNode *lchild,*rchild;
}BinNode,*bin_tree;
typedef struct QNode{
BinNode *iter; //队列中保存指向二叉树结点的指针
struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
QueuePtr front,rear;
}LinkQueue;
using namespace std;
void InitQueue(LinkQueue &Q){
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!Q.front)
exit(0);
Q.front->next=NULL;
}
int QueueEmpty(LinkQueue Q){
return (Q.front==Q.rear)?1:0;
}
void EnQueue(LinkQueue &Q,BinNode *e){
QueuePtr p;
p=(QueuePtr)malloc(sizeof(QNode));
if(!p)
exit(0);
p->iter=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
}
BinNode *DeQueue(LinkQueue &Q){
QueuePtr p;
BinNode *e;
if(Q.front==Q.rear)
exit(0);
p=Q.front->next;
e=p->iter;
Q.front->next=p->next;
if(Q.rear==p)
Q.rear=Q.front;
free(p);
return e;
}
BinNode *CreateTree(bin_tree &T){
VertexType ch;
cin>>ch;
if(!cin.eof()){
if(ch=='#')
T=NULL;
else{
T=(BinNode *)malloc(sizeof(BinNode));
if(!T)
exit(0);
T->data=ch;
T->lchild=CreateTree(T->lchild);
T->rchild=CreateTree(T->rchild);
}
}
return T;
}
void LevelTraverse(bin_tree T){
BinNode *p;
LinkQueue Q;
InitQueue(Q);
if(T){
EnQueue(Q,T);
while(!QueueEmpty(Q)){
p=DeQueue(Q);
cout<<p->data; //如果想要每层的节点从右到左一次输出,可将代码改为注释部分
if(p->lchild) //if(p->rchild)
EnQueue(Q,p->lchild); //EnQueue(Q,p->rchild);
if(p->rchild) //if(p->lchild)
EnQueue(Q,p->rchild); //EnQueue(Q,p->lchild);
}
}
}
void main(){
bin_tree T;
cout<<"请输入二叉树的节点值,输入#代表空树:";
CreateTree(T);
cout<<"二叉树分层遍历的结果是:";
LevelTraverse(T);
cout<<endl;
}