非递归求二叉树高度
假设二叉树采用二叉链表存储结构,设计一个非递归算法求二叉树的高度
算法思想
采用层次遍历的算法,设置遍历level记录当前节点所在的层数,设置变量last指向当前层的最右节点,每次层次遍历出队时与last指针比较,若两者相等,则层数+1,并让last指向下一层的最右节点,直到遍历完成。level的值即为二叉树的高度
如果是空树,高度为0,返回0
初始化front和rear数组队列下标指针
初始化last指向队列中的最右节点,level表示层数
创建一个数组,数据类型是二叉树节点,大小是MaxSize
front和rear初始化为-1,表示队列为空,
rear指向队尾最后一个节点,front指向队头节第一个节点的前一个位置
将根节点入队,先++rear,再把T赋值进去
创建一个工作指针cur访问节点
队列元素出队,即++front,用cur指向出队元素
将当前节点的左孩子右孩子入队
当前front是0,last也是0,front指向的是上一层的最右节点A,last初始化为0,也就是指向A,表示是最右节点,
层数level+1
因为是层序遍历,所以rear指向的就是当前层的最右节点
last指向rear,也就是下一层,指向C
然后继续出队遍历,
front指向的出队元素B不是最右元素,继续出队
front等于last,level++,last指向rear也就是E
继续出队
出到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的宽度(即具有节点数最多的那一层的节点个数)
算法思想
采用层次遍历的方法求出所有节点的层次,并将所有节点和对应的层次放在一个队列中
然后通过扫描队列求出各层的节点总数,最大的层节点总数即为二叉树的宽度
rear++,根节点入队,指针赋给data里的rear下标的位置,层次赋给level里的rear下标的位置
出队,front++,把出队节点,也就是data和level的front下标位置的数据读出来,保存到cur和lv
把左右孩子读进去,把节点和层次也存到相应位置,
直到队空循环结束
用i遍历整个队列
用n统计第lv层的节点个数
lv初始化为1,也就是查找第一层的节点,也就是level数组,如果level的i下标的值等于level表示有一个节点,n++
走完之后,lv等于最后一次i++的下标位置的值,也就是2
然后再开始一轮,
最后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;
}