非递归求二叉树高度
假设二叉树采用二叉链表存储结构,设计一个非递归算法求二叉树的高度
算法思想
采用层次遍历的算法,设置遍历level记录当前节点所在的层数,设置变量last指向当前层的最右节点,每次层次遍历出队时与last指针比较,若两者相等,则层数+1,并让last指向下一层的最右节点,直到遍历完成。level的值即为二叉树的高度
如果是空树,高度为0,返回0
初始化front和rear数组队列下标指针
初始化last指向队列中的最右节点,level表示层数
创建一个数组,数据类型是二叉树节点,大小是MaxSize
![![[Pasted image 20241119090953.png]]](https://i-blog.csdnimg.cn/direct/2d40eff4f2d64617aee725a0679a3c55.png)
front和rear初始化为-1,表示队列为空,
rear指向队尾最后一个节点,front指向队头节第一个节点的前一个位置
将根节点入队,先++rear,再把T赋值进去
![![[Pasted image 20241119091118.png]]](https://i-blog.csdnimg.cn/direct/6b8c9e33ca3a4afbab86d4e1fb1b4a1e.png)
创建一个工作指针cur访问节点
队列元素出队,即++front,用cur指向出队元素
![![[Pasted image 20241119093141.png]]](https://i-blog.csdnimg.cn/direct/052d2d0e153841e381a61e6e1bb73c06.png)
将当前节点的左孩子右孩子入队
![![[Pasted image 20241119093412.png]]](https://i-blog.csdnimg.cn/direct/e10ffb61e3ce4a748bce1da01c19dfec.png)
当前front是0,last也是0,front指向的是上一层的最右节点A,last初始化为0,也就是指向A,表示是最右节点,
层数level+1
因为是层序遍历,所以rear指向的就是当前层的最右节点
last指向rear,也就是下一层,指向C
然后继续出队遍历,
![![[Pasted image 20241119094158.png]]](https://i-blog.csdnimg.cn/direct/dd2e91c0f0054d3385cad6455320c876.png)
front指向的出队元素B不是最右元素,继续出队
![![[Pasted image 20241119094215.png]]](https://i-blog.csdnimg.cn/direct/c2d9f0fbfa614d92bee141b2f803addd.png)
front等于last,level++,last指向rear也就是E
继续出队
![![[Pasted image 20241119094302.png]]](https://i-blog.csdnimg.cn/direct/7907c022194447268d056aa371ea3308.png)
出到E,front等于last,level++
int BTdepth(BTNode* T)
{
if (!T)
// 树空,高度为0
return 0;
int front = -1, rear = -1;
// last指向当前层的最右节点
int last = 0, level = 0;
// 设置队列Q,元素是二叉树节点指针且容量足够
BTNode Q[MaxSize];
// 将根节点入队
Q[++rear] = T;
BTNode* cur;
// 队不空则循环
while (front < rear)
{
// 队列元素出队,即正在访问的节点
cur = Q[++front];
if (cur->left)
// 左孩子入队
Q[++rear] = cur->left;
if (cur->right)
// 右孩子入队
Q[++rear] = cur->right;
// 处理该层的最右节点
if (front == last)
{
// 层数加1
level++;
// last指向下一层
last = rear;
}
}
return level;
}
求非空二叉树宽度
假设二叉树采用二叉链表存储结构,设计一个算法,求非空二叉树b的宽度(即具有节点数最多的那一层的节点个数)
算法思想
采用层次遍历的方法求出所有节点的层次,并将所有节点和对应的层次放在一个队列中
然后通过扫描队列求出各层的节点总数,最大的层节点总数即为二叉树的宽度
![![[Pasted image 20241119135323.png]]](https://i-blog.csdnimg.cn/direct/1a668bf4bc684aacb05cd6c65a21c027.png)
rear++,根节点入队,指针赋给data里的rear下标的位置,层次赋给level里的rear下标的位置
![![[Pasted image 20241119135445.png]]](https://i-blog.csdnimg.cn/direct/b80b4b7c9ecf4797ac44bec11f6b3144.png)
出队,front++,把出队节点,也就是data和level的front下标位置的数据读出来,保存到cur和lv
把左右孩子读进去,把节点和层次也存到相应位置,
![![[Pasted image 20241119140153.png]]](https://i-blog.csdnimg.cn/direct/d27895f8ee1446b1a594ea5e16ac3ed2.png)
![![[Pasted image 20241119140933.png]]](https://i-blog.csdnimg.cn/direct/6a58e7dfcf8b4f6883880f36a95438c5.png)
直到队空循环结束
![![[Pasted image 20241119141018.png]]](https://i-blog.csdnimg.cn/direct/4980ed43507842d58d3f48e076b51ae6.png)
用i遍历整个队列
![![[Pasted image 20241119141331.png]]](https://i-blog.csdnimg.cn/direct/c257432118584486895279c06a9741cd.png)
用n统计第lv层的节点个数
lv初始化为1,也就是查找第一层的节点,也就是level数组,如果level的i下标的值等于level表示有一个节点,n++
走完之后,lv等于最后一次i++的下标位置的值,也就是2
![![[Pasted image 20241119141356.png]]](https://i-blog.csdnimg.cn/direct/cd89ba0fd1b44a2b9fa107585bc92111.png)
然后再开始一轮,
最后max=2
typedef struct
{
// 保存队列中的节点指针
BTNode* data[MaxSize];
// 保存data中相同下标节点的层次
int level[MaxSize];
int front, rear;
}Que;
int BTWidth(BTNode* T)
{
BTNode* = cur;
int lv, max, i, n;
// front=rear=-1,队列为空
Que.front = Que.rear = -1;
// 根节点入队
Que.rear++;
Que.data[Que.rear] = T;
// 根节点层次为1
Que.level[Que.rear] = 1;
// 当队列不为空
while (Que.front < Que.rear)
{
// 出队
Que.front++;
// 读取出队节点
cur = Que.data[Que.front];
// 保存出队节点的层次
lv = Que.level[Que.front];
// 左孩子进队列
if (cur->left)
{
Que.rear++;
// 进保存指针的数组
Que.data[Que.rear] = cur->left;
// 进保存层次的数组
Que.level[Que.rear] = lv + 1;
}
// 右孩子进队列
if (cur->right)
{
Que.rear++;
Que.data[Que.rear] = cur->right;
Que.level[Que.rear] = lv + 1;
}
}
// max保存同一层最多的节点个数
max = 0;
i = 0;
// lv表示从第一层开始找
lv = 1;
// i扫描队中的所有元素
while (i <= Que.rear)
{
// n统计第lv层的节点个数
n = 0;
while (i <= Que.rear && Que.level[i] == lv)
{
n++;
i++;
}
lv = Que.level[i];
// 保存最大的n
if (n > max)
max = n;
}
return max;
}

被折叠的 条评论
为什么被折叠?



