思想:采用基于层序遍历的方法。用level扫描各层节点,若某一层的节点出队后,rear指向该层中最右节点,则将rear赋值给last(对于第一层,last=1).在出队时,若front=last,表示这一层处理完毕,让层号level增1,并置last为下一层最右节点。那么如何求一层的最右节点呢?这是因为第一层只有一个节点,它就是最右节点。对于其他层,上一层最右节点最后进队的孩子一定是该层的最右节点。
例如,对于如图所示的二叉树,求k=3的叶子节点个数的过程如下:level=1;A进队时rear=1,last=rear=1,出队front=1,再将B和C进队,此时rear=3,由于last=front成立,表示处理下一层,让last=rear=3,level=level+1=2; 出队front=2即B节点,将D和E进队,出队front=3即C节点,将F进队,此时rear=6,由于front=rear成立,表示处理下一层,让last=rear=6,level=level+1=3;出队D(front=4),level=k且D为叶子节点,则leaf=leaf+1=1,出队E(front=5),level=k且E为叶子节点,则leaf=leaf+1=2,出队F(front=6),level=k且F为叶子节点,则leaf=leaf+1=3,由于front=last成立,表示处理下一层,让last=rear=6(没有新节点进队),level=level+1=4;level>k,返回leaf=3.
对应的算法如下:
int LeafKLevel(BTNode *b,int k)
{
BTNode *Qu[MaxSize]; //定义循环队列
int front, rear; //定义队首、队尾指针
int leaf=0; //leaf累计叶子节点个数
int last; //定义当前层中最右节点在队列中的位置
int level; //定义当前节点的层号
front=rear=0; //置队列为空队列
if(b==NULL||k<=1)
return 0;
rear=(rear+1)%MaxSize; //节点指针进队
Qu[rear]=b;
last=rear;level=1; //第一层的最右节点在队列中的位置为1
while(front!=rear) //队列不为空时循环
{
front=(front+1)%MaxSize;
b=Qu[front]; //队头出队
if(level==k&&b->lchild==NULL&&b->rchild==NULL)
leaf++; //若*b为level层叶子节点,则递增1
if(b->lchild!=NULL) //左孩子进队
{
rear=(rear+1)%MaxSize;
Qu[rear]=b->lchild;
}
if(b->rchild!=NULL) //右孩子进队
{
rear=(rear+1)%MaxSize;
Qu[rear]=b->rchild;
}
if(front==last) //同层最右节点处理完毕,层数增1
{
level++;
last=rear; //让last指向下一层的最右节点在队列中的位置
}
if(level>k) //当层号大于k时返回leaf,不再继续
return leaf;
}
}
对于如图所示的二叉树,求各层叶子节点个数结果如图所示:
二叉树:A(B(D(,G)),C(E,F))
第1层叶子节点的个数=0
第2层叶子节点的个数=0
第3层叶子节点的个数=2
第4层叶子节点的个数=1
版权声明:本文为博主原创文章,未经博主允许不得转载。
设计一个算法,求非空二叉树中指定的第k层(k>1)的叶子节点的个数
原文地址:http://blog.csdn.net/wuruiaoxue/article/details/46768301