二叉树进行层次遍历:首先搜索第1层根节点F,然后搜索第2层,从左向右C、E,再搜索第3层,从左向右A、D、H、G,再搜索第4层B、M。
创建二叉树节点为空时用# 代替
上图二叉树的先序遍历结果为:FCA##DB###EH##GM###
先序创建二叉树,再层次遍历二叉树,层次遍历的结果 FCEADHGBM
#include <iostream>
#include <queue> //引入队列头文件
using namespace std;
typedef struct Bnode/*定义二叉树存储结构*/
{
char data;
struct Bnode *lchild,*rchild;
}Bnode,*Btree;
void Createtree(Btree &T)/*创建二叉树函数*/
{
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
cin >> ch;
if(ch=='#')
T=NULL;//递归结束,建空树
else{
T=newBnode;
T->data=ch;//生成根结点
Createtree(T->lchild);//递归创建左子树
Createtree(T->rchild);//递归创建右子树
}
return;
}
bool Leveltraverse(Btree T)
{
Btree p;
if(!T)
return false;
queueQ;//创建一个普通队列(先进先出),里面存放指针类型
Q.push(T);//根指针入队
while(!Q.empty())//如果队列不空
{
p=Q.front();//取出队头元素作为当前扩展结点livenode
Q.pop();//队头元素出队
cout<<p->data<<"\t";
if(p->lchild)
Q.push(p->lchild);//左孩子指针入队
if(p->rchild)
Q.push(p->rchild);//右孩子指针入队
}
return true;
}
int main()
{
Btree mytree;
cout<<"按先序次序输入二叉树中结点的值(孩子为空时输入#),创建一棵二叉树"<
Createtree(mytree);//创建二叉树
cout<<"二叉树的层次遍历结果:"<
Leveltraverse(mytree);//层次遍历二叉树
return 0;
}
层次遍历思想的相关算法
1.层次遍历访问每个结点(自上而下,从左到右)
- 按照箭头所指方向对二叉树的各个结点进行访问。要进行层次遍历,需要借助一个队列。首先对二叉树的根结点入队,然后出队,访问出队结点,若它有左子树,则将左子树根结点入队;若它有右子树,则将右结点入队。完成入队后出队,访问出队结点······如此反复,直至队列为空。
void levelOrder(BiTree T){
InitQueue(Q);
BiTree p;
EnQueue(Q,T);
while(!IsEmpty Q){
DeQueue(Q,p);
visit(p);
if(p->lchild)
EnQueue(Q,p->lchild);
if(p->rchild)
EnQueue(Q,p->rchild);
}
}
2.层次遍历访问每个结点(自下而上,从右到左)
- 利用原有的层次遍历算法,出队的同时将各个结点指针入栈,在所有结点入栈后再从栈顶开始依次访问即为所求。
void InvertLevel(BiTree T) {
Stack s;
Queue(Q);
if(T) {
InitStack (s);
InitQueue(Q);
EnQueue(Q,T);
while(!IsEmpty Q) {
DeQueue(Q,p);
Push(s,p);
if(p->lchild)
EnQueue(Q,p->lchild);
if(p->rchild)
EnQueue(Q,p->rchild);
}
while(!IsEmpty s) {
Pop(s,p);
visit(p->data);
}
}
}
3.求二叉树的高度
int Btdepth(BiTree T) {
if(T==null) {
return 0;
}
ldep=Btdepth(BiTree T->lchild);
rdep=Btdepth(BiTree T->rchild);
if(ldep>rldep)
return ldep+1;
else
return rdep+1;
}
4.求二叉树的最大宽度
- 按照层次遍历的思路,我们将根结点入队,然后出队,temp表示二叉树每层的结点个数,每次出队一个元素temp++,然后把根节点的左右孩子入队,判断front指针是否大于last(每层结点最后元素的位置),即判断这一层的元素是否全部出队(全部出队则front与上一次的rear相等,即大于last(rear-1)),如果全部出队则更新last,max(最大宽度)和temp,最后递归所有元素然后返回最大宽度max。
int WidthBiTree(BiTree T) {
if(!T) return 0;//空树
Queue Q;
//temp为树每层的结点个数 ,last为一层中最后一个结点在队列的位置
int temp=0,last=0,max=0;
InitQueue(Q);
EnQueue(Q,T);
while(Q.front <= last) { //每出队一个元素front+1
DeQueue(Q, T);
temp++;
if (e->lchild != NULL)//每次入队rear+1
EnQueue(Q, T->lchild);
if (e->rchild != NULL)
EnQueue(Q, T->rchild);
//判断这一层的元素是否全部出队
if (Q.front > last) {
last = Q.rear-1;
max = max > temp ? max : temp;
temp = 0;
}
}
return max;
}
5.求二叉树第k层的结点个数
int TreeKLevelSize(BiTree T, int k) {
if (T == NULL||k<1)
return 0;
if (k == 1)
return 1;
else {
k--;
return TreeKLevelSize(T->lchild, k) + TreeKLevelSize(T->rchild, k);
}
}
6.求二叉树的结点总数
int NodeCount(BiTree T) {
if (T == NULL)
return 0;
else
return NodeCount(T->lchild) + NodeCount(T->rchild)+1;
}
7.指定结点值在二叉排序树中的层次
- 遍历二叉排序树,由二叉排序树的性质(左子树<根结点<右子树的值),通过比较结点的值,若等于根结点的值,返回1;若小于根结点的值,遍历左子树;同样大于根结点的值,遍历右子树。每下一层,就将层次加1,直到找到指定结点,就可以求出其所在层次。
int find_level(BiTree T, BTNode p) {
int n=1;
if(T!=NULL) {
while(T->data!=p->data) {
if(T->data<p->data)
T=T->rchild;
else
T=T->lchild;
n++;
}
}
return n;
}