一、题目描述
有些地方原题说得不太清楚,我按照自己的语言说一遍。
输入是若干棵二叉树,先序遍历,权值代表从该点竖直落下的叶片数量,没有风将任何节点落下的叶片吹到其它地方去。每个节点的左子树比该节点的水平坐标减少一个单位,右子树比该节点的水平坐标增加一个单位,两个子树的垂直坐标比父节点减少一个单位。要求统计处在每个水平位置全部节点的权值之和(作为该处落下的叶片的总数)。如果一个节点的左子树或右子树不存在,对应的值为 -1 。如果子节点的位置已经存在别的节点,这个位置的值要累加。垂直坐标不会超过 80 个。每种情形输出以后要额外再空一行。根节点为 -1 时,输入结束。
复习先序遍历的递归定义:
PreOrder(N) = Root(N) + PreOrder(NL) + PreOrder(NR)
N、NL、NR 分别代表节点、左节点、右节点。从根节点开始,将其左节点和右节点继续套用此式展开,直到全部子树展开完毕为止。+ 运算符在这里是一种广义的运算符,可以代表字符串连接等运算。
如果仍然不理解,请根据下述说明一步一步在草稿纸上画出二叉树。
样例说明:
5 7 -1 6 -1 -1 3 -1 -1
根节点为 5 。5 的左子节点为 7 。7 的左子节点不存在,右子树为 6 。6 的左子树和右子树均不存在。此时根节点 5 的左子树输入完毕,开始输入其右子树。5 的右子节点的权为3,3的子节点不存在。整个二叉树输入完毕。其构造如下:
第一、二、三列的和分别为 7、11、3 ,所以输出:
Case 1:
7 11 3
8 2 9 -1 -1 6 5 -1 -1 12 -1
-1 3 7 -1 -1 -1
根节点为 8 ,8 的左节点为 2 ,2 的左节点为 9 ,9 的左右节点均不存在。2 的右节点为 6 ,6 的左节点为 5 ,5 的左右节点均不存在。6 的右节点为 12 ,12 无子节点。根节点 8 的左子树输入完毕,开始输入 8 的右子树。8 的右子节点为 3 ,3 的左子节点为 7 ,但该位置已经存在值 6 ,所以该位置的值改为 13 。7 也无左右节点。3 无右节点。二叉树输入完毕,其构造如下:
第一、二、三、四列的和分别为 9、7、21、15,输出:
Case 2:
9 7 21 15
二、算法分析说明与代码编写指导
采用递归输入,写成专门的建树函数读入每个数值,每次读入一个数值相当于读入一个节点,然后在函数内再调用该函数去读这个节点的左子树和右子树。如果读取到 -1 就直接返回,否则累加在该水平位置落下的树叶的数量。这样就可在主程序中只调用一次建树函数就能读入数值直到二叉树构造完毕。
因为最多有80列,所以可用一个数组 sum[81] 来统计每一列落下的叶片数量。初始位置从 40 开始,并用变量 L 和 R 分别记录整个二叉树到达的最左端与最右端的水平位置,变量 p 记为当前位置。输出只要输出