1.二叉树层次遍历的原理
算法思想:
利用队列实现的,因为层次遍历的序列正好符合队列的特性,先进先出,所以用队列这个工具实现二叉树的层次遍历
但pay attention to 这里我用的是循环队列,因我害怕队列溢出,导致内存泄漏的不规范行
2.代码如下
#include<iostream> #include<cstdio> #include<cstdlib> #define MaxSize 50 using namespace std; typedef char ElemType; //树结点定义 typedef struct node{ ElemType data; struct node* lchild,*rchild; }BiTNode,*BiTree; //采用循环队列定义 typedef struct{ BiTree value[MaxSize]; int front,rear; }Qunue; //初始化循环队列 void InitQunue(Qunue &Q) { Q.front=Q.rear=0; } //入队操作 bool EnQunue(Qunue &Q,BiTree x) { //入队判断队列是否满了 if((Q.rear+1)%MaxSize==Q.front) { printf("循环队列已经满了,无法入队了! "); return false; } else{ Q.value[Q.rear]=x; Q.rear=(Q.rear+1)%MaxSize; return true; } } //出队操作 bool DeQunue(Qunue &Q,BiTree &x) { //出队操作判断队列是否为空 if(Q.rear==Q.front) { printf("队列为空,无法出队! "); return false; } else{ x=Q.value[Q.front]; Q.front=(Q.front+1)%MaxSize; return false; } } //判断队列是否为空 bool EmpytQunue(Qunue Q) { if(Q.rear==Q.front) { return true; } else{ return false; } } //初始化一个空的二叉树 void InitBiTree(BiTree &tree) { // tree存储NULL,表示没有二叉树 tree=NULL; } //先序递归创建二叉树 #表示空结点 //eg: 12#### 表示的是根为1,左孩子为2 void CreateBitree(BiTree &T) { char ch; if((ch=getchar())=='#') T=NULL; else { T=(BiTNode*)malloc(sizeof(BiTNode)); T->data=ch; CreateBitree(T->lchild); CreateBitree(T->rchild); } } //层次遍历 bool LevelOrder(BiTree &tree) { Qunue Q; 初始化一个循环队列 InitQunue(Q); BiTree p=tree,q,r; //保护 if (p) { EnQunue(Q,p); //先把根节点入队,为了构造循环结束的条件,队列为空 } else{ cout<<"二叉树为空,无法进行层次遍历!"<<endl; return false; }; while(!EmpytQunue(Q)) { if(p->lchild) //左孩子结点存在,入队 { EnQunue(Q,p->lchild); } if (p->rchild) //右孩子节点存在入队 { EnQunue(Q,p->rchild); //当处理完下一行时,上一行的左结点出队包括根节点(其实也可一全进入队列里最后在统一出队,都可以) DeQunue(Q,p); //出队列 printf("%c",p->data); //输出结点值 if(p->lchild==NULL) //if-else 为了,让p指向下一行的左结点或者右结点(因为右结点可能不存在) p=p->rchild; else p=p->lchild; } if(p->lchild==NULL&&p->rchild==NULL) //当p的左右都为空时,结束层次遍历 while (!EmpytQunue(Q)) { DeQunue(Q,p); printf("%c",p->data); //输出队列中保存的所有结点数据 } } return true; } int main() { BiTree tree; //创建一个二叉树结点指针 InitBiTree(tree); //初始化一个空二叉树 CreateBitree(tree); //先序递归创建一个二叉树 LevelOrder(tree); //层次遍历结果序列 return 0; }
#include<iostream> #include<cstdio> #include<cstdlib> #define MaxSize 50 using namespace std; typedef char ElemType; //树结点定义 typedef struct node{ ElemType data; struct node* lchild,*rchild; }BiTNode,*BiTree; //采用循环队列定义 typedef struct{ BiTree value[MaxSize]; int front,rear; }Qunue; //初始化循环队列 void InitQunue(Qunue &Q) { Q.front=Q.rear=0; } //入队操作 bool EnQunue(Qunue &Q,BiTree x) { //入队判断队列是否满了 if((Q.rear+1)%MaxSize==Q.front) { printf("循环队列已经满了,无法入队了! "); return false; } else{ Q.value[Q.rear]=x; Q.rear=(Q.rear+1)%MaxSize; return true; } } //出队操作 bool DeQunue(Qunue &Q,BiTree &x) { //出队操作判断队列是否为空 if(Q.rear==Q.front) { printf("队列为空,无法出队! "); return false; } else{ x=Q.value[Q.front]; Q.front=(Q.front+1)%MaxSize; return false; } } //判断队列是否为空 bool EmpytQunue(Qunue Q) { if(Q.rear==Q.front) { return true; } else{ return false; } } //初始化一个空的二叉树 void InitBiTree(BiTree &tree) { // tree存储NULL,表示没有二叉树 tree=NULL; } //先序递归创建二叉树 #表示空结点 void CreateBitree(BiTree &T) { char ch; if((ch=getchar())=='#') T=NULL; else { T=(BiTNode*)malloc(sizeof(BiTNode)); T->data=ch; CreateBitree(T->lchild); CreateBitree(T->rchild); } } //层次遍历 bool LevelOrder(BiTree &tree) { Qunue Q; InitQunue(Q); BiTree p=tree,q,r; //保护 if (p) { EnQunue(Q,p); //先把跟入队,为了判断 } else{ cout<<"二叉树为空,无法进行层次遍历!"<<endl; return false; }; while(!EmpytQunue(Q)) { if(p->lchild) { q=p->lchild; EnQunue(Q,p->lchild); } if (p->rchild) { EnQunue(Q,p->rchild); DeQunue(Q,p); //出队列 第二种逻辑控制,一次出对两个,正好把p赋值成左结点了 printf("%c",p->data); DeQunue(Q,p); printf("%c",p->data); // if(p->lchild==NULL) // p=p->rchild; // else // p=p->lchild; } if(p->lchild==NULL&&p->rchild==NULL) //当p的左右都为空时,结束层次遍历 while (!EmpytQunue(Q)) { DeQunue(Q,p); printf("%c",p->data); } } return true; } int main() { BiTree tree; InitBiTree(tree); CreateBitree(tree); LevelOrder(tree); return 0; }
#include<iostream> #include<cstdio> #include<cstdlib> #define MaxSize 50 using namespace std; typedef char ElemType; //树结点定义 typedef struct node{ ElemType data; struct node* lchild,*rchild; }BiTNode,*BiTree; //采用循环队列定义 typedef struct{ BiTree value[MaxSize]; int front,rear; }Qunue; //初始化循环队列 void InitQunue(Qunue &Q) { Q.front=Q.rear=0; } //入队操作 bool EnQunue(Qunue &Q,BiTree x) { //入队判断队列是否满了 if((Q.rear+1)%MaxSize==Q.front) { printf("循环队列已经满了,无法入队了! "); return false; } else{ Q.value[Q.rear]=x; Q.rear=(Q.rear+1)%MaxSize; return true; } } //出队操作 bool DeQunue(Qunue &Q,BiTree &x) { //出队操作判断队列是否为空 if(Q.rear==Q.front) { printf("队列为空,无法出队! "); return false; } else{ x=Q.value[Q.front]; Q.front=(Q.front+1)%MaxSize; return false; } } //判断队列是否为空 bool EmpytQunue(Qunue Q) { if(Q.rear==Q.front) { return true; } else{ return false; } } //初始化一个空的二叉树 void InitBiTree(BiTree &tree) { // tree存储NULL,表示没有二叉树 tree=NULL; } //先序递归创建二叉树 #表示空结点 void CreateBitree(BiTree &T) { char ch; if((ch=getchar())=='#') T=NULL; else { T=(BiTNode*)malloc(sizeof(BiTNode)); T->data=ch; CreateBitree(T->lchild); CreateBitree(T->rchild); } } //层次遍历 bool LevelOrder(BiTree &tree) { Qunue Q; InitQunue(Q); BiTree p=tree; //保护 if (p) { EnQunue(Q,p); //先把跟入队,为了判断 } else{ cout<<"二叉树为空,无法进行层次遍历!"<<endl; return false; }; while(!EmpytQunue(Q)) { DeQunue(Q,p); printf("%c",p->data); //这里放置访问结点的各种操作 这里用的只是输出 if(p->lchild) { EnQunue(Q,p->lchild); } if (p->rchild) { EnQunue(Q,p->rchild); } } return true; } int main() { BiTree tree; InitBiTree(tree); CreateBitree(tree); LevelOrder(tree); return 0; }
本质都是一样的,只不过改了改逻辑.