层次遍历思想相关算法

二叉树进行层次遍历:首先搜索第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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上岸啦小王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值