二叉树的垂直总和

时间:2012-03-10 12:53:17

标签: algorithm data-structures binary-tree

如何查找二叉树的垂直和。

例如, 考虑下面的二叉树,

                      1
                    /  \
                   /    \
                  /      \
                 2        3
                / \      / \
               /   \    /   \
               4   5    6    7
              / \ / \  / \  / \
             5  9 1  3 6 7 5   5

对于上述树,垂直和应按如下方式计算,

  • 第1行:5
  • 第2行:4
  • 第3行:2,9,1
  • 第4行:5
  • 第5行:1,3,6
  • 第6:6行
  • 第7行:3,7,5
  • 第8:7行
  • 第9行:5

输出应为:

5,4,12,5,10,6,15,7,5

3 个答案:

答案 0 :(得分:7)

首先你应该找到这些位置,你可以通过计算剩余数量和权利支出来达到特定节点:

                 1     : l = 0, r = 0
                / \
               /   \
      l=1,r=0 2     3  : l = 0, r = 1.
             / \   / \
     ...    4...5 6...7 ....

只需遍历二叉树,最后为每个节点计算LorR = NumberOfLeft - NumberOfRights,然后将这些数字(按LorR值)组合在一起,找出每个组的总和(从最正面到最正面打印)负值LorR)。

更新:这对于高度超过2的树没有答案,我们可以通过算法进行少量修改来解决这个问题。

我们可以看到树作为金字塔,金字塔的每个顶点都有长度1,在每个分支剩余部分的分支等于最新移动中传递的内容之后,我们在图片中显示高度为3的树:

                  1
                /  \
               /    \
              /      \
             2        3    upto this we used 1/2 size of pyramid
            / \      / \
           /   \    /   \
           4   5    6    7  upto this we used 1/2 + 1/4 part of pyramid
          / \ / \  / \  / \
         5  9 1  3 6 7 5   5  upto this we used 1/2 + 1/4 + 1/4 part of pyramid

这意味着在每一步中我们都根据它们的高度来计算左边的值(事实上,每次乘以1/2的乘数都会被加到左边的值,除了上一次,它等于h-1 st值)。

因此对于这种情况我们有:1在根中是在组0中,3在叶中是在组-1/2 + 1/4 + 1/4 = 0,6中在叶中是在组1/2 - 1 / 4 - 1/4 = 0

叶子中的

1是-1/2 + 1/4 - 1/4 = -1/2,依此类推。

为了防止将1 /(2 ^ x)舍入为零或其他问题,我们可以将我们的因子(1 / 2,1 / 4,1 / 8,...)乘以2 h-1 。事实上,在我写的第一个案例中,我们可以说因子乘以2 2-1

Related Pyramid for tree of height 4

答案 1 :(得分:2)

据我所知左移是-1,向右移动是+1。您可以使用修改后的dfs。假设add(col, value)已定义

dfs(col, node)
begin
  add(col, node.value)
  if(haveLeft)
     dfs(col-1, left)
  if(haveRight)
     dfs(col+1, right)
end

假设该添加在O(1)中起作用(例如使用HashMap或简单数组),这适用于O(n)。

答案 2 :(得分:1)

伪代码中的强力方法:

columnAdd(tree):
  sumPerColumn = new Map<int,int>();
  traverse(tree.root, sumPerColumn, 0);
  return sumPerColumn;

traverse(node, sumPerColumn, currentColumn):
  sumPerColumn[currentColumn] ++;
  traverse(node.left, sumPerColumn, currentColumn-1);
  traverse(node.right, sumPerColumn, currentColumn+1);

这会产生:

  {-2: 4,
   -1: 2,
    0: 12,
    1: 3,
    2: 7}