假设二叉树采用二叉链表存储结构存储, 设计一个算法, 求出该二叉树的宽度(即具有结点数最多的那一层上的结点个数)。
给出算法的基本设计思想。
要求含有最大结点数的层上的结点数, 可以分别求出每层的结点数, 然后从中选出最大的。 要达到这个目的, 应该明白两个事实。
①对于非空树, 树根所在的层为第一层, 这个是显然的, 并且从层次遍历算法的程序中可以发现, 有一个由当前结点找到其左、 右孩子结点的操作。 这就提示我们, 如果知道当前结点的层号, 就可以推出其左、 右孩子的层号, 即为当前结点层号加 1, 进而可以求出所有结点的层号。
②在层次遍历中, 用到了一个循环队列(队列用数组表示), 其出队和入队操作为 front=(front+1)%maxSize和 rear=(rear+1) %maxSize 两句。 如果用来存储队列的数组足够长, 可以容纳树中所有结点, 这时在整个遍历操作中队头和队尾指针不会出现折回数组起始位置的情况, 那么 front=(front+1) %maxSize 可以用++front代替, rear=(rear+1) %maxSize 可以用++rear 代替。 出队操作只是队头指针 front 后移了一位并没有把队头元素删除, 在数组足够长的情况下队头元素也不会被新入队的元素覆盖。 搞清了上边两件事情后, 这个题目就好解决了。
③由①可以算出所有结点的层号。 由②可以知道所访问的结点最终保存在数组里。 因此我们只需修改层次遍历算法模板, 在其中添加上求层号的操作, 并且将循环队列的操作改为非循环队列的操作, 在遍历结束后, 数组中记录了树中所有结点层号信息, 进而可以求出含有结点最多的层上的结点数。
根据设计思想, 采用 C 或 C++语言描述算法, 并在关键之处给出注释。
由此可以写出以下程序: