任务描述
相关知识
求二叉树高度的递归算法
求二叉树总节点数的递归算法
编程要求
测试说明
任务描述
本关任务:给定一棵二叉树,计算该二叉树的高度、总节点个数和叶子节点个数。
相关知识
为了完成本关任务,你需要掌握:1.二叉树高度概念,2.二叉树节点,3.二叉树叶子节点概念。
求二叉树高度的递归算法
二叉树高度概念
二叉树的高度指的是二叉树中最大的结点层数。例如:图1所示的二叉树最大的节点层数为3,所以该二叉树高度为3。
二叉树高度的递归算法思想
递归算法设计便是从递归数据结构的基本递归运算入手的。
对于二叉树,以二叉链为存储结构,其基本递归运算就是求一个结点b的左子树(b->lchild)和右子树(b->rchild)。
b->lchild和b->rchild一定是一棵二叉树(这是为什么二叉树的定义中空树也是二叉树的原因)。
一般地,二叉树的递归结构如下:
对于二叉树b,设f(b)是求解的“大问题”。
f(b->lchild)和f(b->rchild)为“小问题”。
假设f(b->lchild)和f(b->rchild)是可求的,在此基础上得出f(b)和f(b->lchild)、f(b->rchild)之间的关系,从而得到递归体。
再考虑b=NULL或只有一个结点的特殊情况,从而得到递归出口。
例如,采用二叉链表存储结构,求该二叉树的高度。
算法思想:
空树的高度为0:如果该节点不存在,返回树高度为0;
分别递归计算左子树和右子树高度,取左子树和右子树高度中的较大值加1为当前二叉树高度。
即设f(b)为二叉树b的高度:
当b=NULL时,f(b)=0。
当b!=NULL时,f(b->lchild)和f(b->rchild)分别为结点b的左、右子树的高度,取f(b->lchild)和f(b->rchild)中较大值加1,即为二叉树b的高度。
显然有:
f(b)=1 + max( f(b->lchild),f(b->rchild) )
求二叉树总节点数的递归算法
二叉树的节点包含一个数据元素及两个指向子树的分支,例如:图1所示的二叉树的总节点个数为6。
例如,采用二叉链表存储结构,求该二叉树的节点的个数。
算法思想:
空树的节点数为0:如果该节点不存在,返回节点个数为0;
分别递归计算左子树和右子树的节点数,则当前二叉树的节点数为左、右子树的节点数之和再加1。
即设f(b)为二叉树b的节点数:
当b=NULL时,f(b)=0。
当b!=NULL时,f(b->lchild)和f(b->rchild)分别为结点b的左子树的节点数和右子树的节点数,则二叉树b的节点数为f(b->lchild)+f(b->rchild)+1。
显然有:
f(b)= f(b->lchild)+f(b->rchild)+1
二叉树叶子节点概念
叶子节点是度为0的节点,二叉树节点的度为子树的个数。例如:图1所示的二叉树叶子节点为C,D和F,个数为3。
算法思想:
空树的叶子节点数为0:如果该节点不存在,返回节点个数为0;
如果该节点的左子树和右子树同时为空,返回叶子节点个数为1;
分别递归计算左子树和右子树的叶子节点数,则当前二叉树的节点数为左、右子树的节点数之和。
显然有:
f(b)= f(b->lchild)+f(b->rchild)
编程要求
本关的编程任务是补全右侧代码中 Begin至End中间的代码,具体要求如下:
int BiTreeDepth(BiTree T); //计算该二叉树的深度,返回深度值
int NodeCount(BiTree T); //计算该二叉树的总的节点个数,返回节点个数
int LeafNodeCount(BiTree T); //算该二叉树的叶子节点个数,返回叶子节点个数
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是平台的测试样例:
测试输入:
ABC##D##EF###
预期输出:
该树的高度为:3
节点的数目为: 6
叶子节点的数目为: 3
测试输入:
ABCD###E#F##G##
预期输出:
该树的高度为:4
节点的数目为: 7
叶子节点的数目为: 3
开始你的任务吧,祝你成功!
#include <stdio.h>
#include <stdlib.h>
#include "bitree.h"
int BiTreeDepth(BiTree T);//计算该二叉树的深度,返回深度值
int NodeCount(BiTree T);//计算该二叉树的总的节点个数,返回节点个数
int LeafNodeCount(BiTree T);//算该二叉树的叶子节点个数,返回叶子节点个数
int main()
{
BiTree T;
CreateBiTree(T);
printf("该树的高度为:%d\n",BiTreeDepth(T));
printf("节点的数目为: %d\n",NodeCount(T));
printf("叶子节点的数目为: %d\n",LeafNodeCount(T));
DestoryBiTree(T);
return 0;
}
int BiTreeDepth(BiTree T)
{ // 初始条件:二叉树T存在。操作结果:返回T的深度
/********** Begin **********/
if(T)
{
return BiTreeDepth(T->lchild)>BiTreeDepth(T->rchild)?BiTreeDepth(T->lchild)+1:BiTreeDepth(T->rchild)+1;
}
/********** End **********/
}
int NodeCount(BiTree T)
{
//初始条件:二叉树T存在。操作结果:返回T的结点数
/********** Begin **********/
if(T)
{
return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}
/********** End **********/
}
int LeafNodeCount(BiTree T)
{
//初始条件:二叉树T存在。操作结果:返回T的叶子结点数
/********** Begin **********/
if(T)
{
if(T->lchild==NULL&&T->rchild==NULL)
{
return 1;
}
return LeafNodeCount(T->rchild)+LeafNodeCount(T->lchild);
}
/********** End **********/
}