前言
题目来自王道数据结构一书,归纳经典题目
正文
求二叉树的深度
递归
/*结构体声明*/
typedef struct BiTNode{
struct BiNode *lchild,*rchild;
int data;
// int tag;
}*BiTree,BiTNode;
int Btdepth(BiTree T){
if(T==NULL)
return 0;
ldep=Btdepth(T->lchild);
rdep=Btdepth(T->rchild);
if(ldep>rdep)
return ldep+1;
else
return rdep+1;
}
借用一下这位大佬的图,自己再走一遍流程。https://blog.csdn.net/tudaodiaozhale/article/details/78674671
分析:
首先遍历A层,向A的左子树递归进入B层,到达B层再递归进入其左子树**#层**
发现此时的T为NULL,从#层返回0到B层,B层的ldep已结束,再往下走,进入其右子树rdep,同理进入#层后发现T为NULL返回0到B层。此时B层的左右子树递归都结束了,继续往下走,判断if(ldep>rdep)
ldep和rdep为两个0,返回ldep=rdep+1=1到A层。
此时A层的ldep已经结束了,往下走,进入其右子树rdep,和上面的操作类似最后返回A层时的rdep=rdep+1=2。此时A层的左右子树都遍历完,判断if(ldep>rdep)
,ldep=1,rdep=2,所以返回rdep+1=3,这颗树的深度就是3
非递归
采用层次遍历,设置变量level记录当前结点所在层次,设置变量last指向当前层的最右结点,每次遍历出队时与last指针比较,若两者相等,则层数加1,并让last指向下一层的最右结点,直到遍历完成。
int Btdepth2(BiTree T){
if(!T)
return 0;
int font=-1,rear=-1;
int last=0,lever=0;//last指向当前层的最右结点
BiTree Q[Maxsize];//初始化队列Q,元素是二叉树结点指针
Q[++rear]=T //根结点入队
BiTree p;
while(front<rear){//队不空循环
p=Q[++front];
if(p->lchild)
Q[++rear]=p-lchild;
if(p->rchild)
Q[++rear]=p->rchild;
if(front==last){//处理该层的最右结点
level++; //层数加1
last=rear; //last指向下层
}
}
return level;
}
求二叉树的宽度
非递归
类似于上面求深度的非递归写法,要用一个last值指向当前层的最右结点,每次出一个元素,宽度width+1,若处理到了某一层的最右一个结点,即front==last时,再判断max和width的关系,最后直到队列为空,max就位最二叉树的最宽宽度。
int Btdepth2(BiTree T){
if(!T)
return 0;
int font=-1,rear=-1;
int last=0,ever=0;//last指向当前层的最右结点
int max=0,width=0;//max 保存上一层宽度,width保存本层宽度
BiTree Q[Maxsize];//初始化队列Q,元素是二叉树结点指针
Q[++rear]=T; //根结点入队
BiTree p;
while(front<rear){//队不空循环
p=Q[++front]; width++
if(p->lchild)
Q[++rear]=p-lchild;
if(p->rchild)
Q[++rear]=p->rchild;
if(front==last){//处理该层的最右结点
if(max<width)
max=width; //若该层的宽度大于max,赋值
last=rear;//
width=0;//每一层宽度置空一次
}
}
return max;
}
递归
count[k]数组用来储存每一层的宽度,每次递归k+1代表层次+1,
int Max=0;
int conut_[MaxSize];
int getWidth(BiTree T,int k){ //k变量为当前层数 默认从第一层开始
if(T==NULL)// T为空直接返回
return;
else
conut_[k]++;// T不为空conut_[k]++
if(conut_[k]>Max)
Max=conut_[k]; //Max为数组的最大值
getWidth(T->lchild,k+1);
getWidth(T->Rchild,k+1);
return Max
}