在做PTA作业的时候接触到了这个题,花了一个小时完全弄明白他的原理,我真是笨啊!!!
思考这个问题,怎样才能层序遍历二叉树?
那就是用队列,每当有一个节点出队列,则将这个出队列的节点的左右孩子入队列,这样可以按照层序遍历整个二叉树。
那怎样在层序遍历的基础上将每层二叉树的节点分割开来,即达到累计出每层二叉树节点数目的作用呢?
那就要借助“数量标注”了,所谓数量标注就是设置一个变量来标定你这一层的节点的数量,利用队列入队和出队时队列的队头与队尾位置关系的变化关系来达成分隔二叉树层次的作用。
所以求二叉树宽度的算法的思路就是:
先创建一个队列,用一个标注变量去标注最开始时队尾的位置,然后用一个循环来操作二叉树,循环体内的操作和层序遍历类似,不同的是,在每趟循环结束后都要来判断上一层是否便利完成(用那个标注变量和队首的位置比较)如果便利完成,则刷新最大宽度和bia
typedef struct TreeNode *BinTree;
struct TreeNode
{
int Key;
BinTree Left;
BinTree Right;
};
int Width( BinTree T )
{
BinTree p;
Queue Q;
int Last, temp_width, max_width;
temp_width = max_width = 0;
Q = CreateQueue(MaxElements);
Last = Queue_rear(Q);//标注队尾位置
if ( T == NULL) return 0;
else
{
Enqueue(T, Q);//将二叉树的树根入队列
while (!IsEmpty(Q))
{
p = Front_Dequeue(Q); //由队头出队列一个元素
temp_width++;
if ( p->Left) Enqueue(p->Left, Q);//将出队列的这个元素的左孩子节点入队
if (p->right) Enqueue(p->right, Q);//将出队列的这个元素的右孩子节点入队
if ( Queue_front(Q) > Last ) //判断上一层是否遍历完
{
Last = Queue_rear(Q);//更新标注变量的值
if ( temp_width > max_width ) max_width = temp_width;
temp_width = 0;
} /* end-if */
} /* end-while */
return max_width;
} /* end-else */
}