核心思想:二叉树层次i的结点遍历结束后,层次i+1的结点已全部进队,此时队列的元素个数即为层次 i + 1的宽度
难点:如何判断二叉树层次i已经遍历结束呢?可采用一个变量width记录层次i的结点个数,每出队一个元素,变量width减一,当width == 0时,表明层次i遍历完毕。
二叉树层次i遍历结束后(width == 0),只需要用当前队列的元素个数来更新width,表示二叉树层次i + 1的结点个数
int BTWidth(BTNode *b)
{
if(b == NULL) //为空树,返回宽度为0
return 0;
int width, max;
int i = 1, max_i; //初始化二叉树层次i,最大宽度所在层次max_i
BTNode * p;
SqQueue * qu;
InitQueue(qu); //初始化层次遍历需要借助的队列
enQueue(qu, b); //树不为空,根节点进队
width = 1; // 宽度置为1
max = width; //最大宽度为1
max_i = i; //最大宽度所在层次
while(!QueueEmpty(qu)) //队列为空,表明二叉树遍历完毕,退出循环
{
deQueue(qu, p); //节点出队,赋给p
width --; //出队一次,width减1
if(p -> lchild != NULL) //出队节点的左孩子进队
enQueue(qu, p -> lchild);
if(p -> rchild != NULL)
enQueue(qu, p -> rchild); //出队节点的右孩子出队
if(width == 0) //width == 0,表示当前层次i所有节点已遍历完毕
{ //此时队列元素个数即为下一层次 i + 1 的节点个数
width = (qu->rear - qu->front + MaxSize) % MaxSize; //更新宽度
i++; //层次变为下一层 i + 1
if(width > max) //如果层次 i + 1 宽度 > max
{
max = width; //更新max
max_i = i; //并记录最大宽度所在层次
}
}
}
printf("二叉树层次 %d 的宽度最大\n", max_i);
return max;
}