【问题标题】:Find sum of nodes height in a binary tree recursively递归查找二叉树中节点高度的总和
【发布时间】:2015-09-12 19:51:59
【问题描述】:

如何递归求二叉树中节点的高度之和?

例子:

public int totalHeight() {
    return totalHeight(root);
}

private int totalHeight(BinaryNode<AnyType> n) {

    int totalHeight = 0;

    if (n.left == null && n.right == null)
        return totalHeight;
    if (n.left != null && n.right != null)
        return totalHeight + 1
                + Math.max(totalHeight(n.left), totalHeight(n.right));
    if (n.left != null)
        return totalHeight + 1 + Math.max(totalHeight(n.left), -1);
    if (n.right != null)
        return totalHeight + 1 + Math.max(-1, totalHeight(n.right));

    return totalHeight;
}

我试过这个,但它只得到树的高度而不是所有节点高度的总和。

我觉得很难在递归中跟踪计数器,似乎totalHeight 每次递归调用都设置为0。这不好。

【问题讨论】:

  • 此方法为您提供单个节点的高度。如果您要创建另一个函数并将其应用于树中的每个节点并添加结果会怎样?这将是 O(n^2*log n) (这很糟糕)但会起作用。
  • 使用全局变量来跟踪总数。

标签: java recursion binary-tree


【解决方案1】:

一个简单的版本是执行两遍过程,首先记录每个节点的高度,然后遍历节点以总结它们。这种方法可以递归,但很容易在计算高度时通过求和来完成。

public static int totalHeightSum = 0;

private int calculateHeightAndAdd ( Node n )
{
     if ( n == null )
        return 0;

     int leftHeight = calculateHeightAndAdd ( n.left );
     int rightHeight= calculateHeightAndAdd ( n.right);

     int myHeight = 1 + Math.max ( leftHeight, rightHeight );

     totalHeightSum += myHeight;

     return myHeight;
}

【讨论】:

  • 如果(n == null)返回0;而不是 return 0 ,-1 应该在那里。
【解决方案2】:

递归查找每个节点的高度并不断添加到静态变量。或者,您可以记住高度并存储在每个节点中,然后再进行一次递归以将它们相加。

递归应该返回节点 n 的高度,而不是子树中每个节点的总高度。

【讨论】:

    【解决方案3】:

    鉴于您对节点高度的实现,我们简单地称它为height(BinaryNode&lt;?&gt;),您可以:

    如果您可以访问集合中的所有节点:

    int sumHeight(List<BinaryNode<?>> nodes) {
        int sum = 0;
        for (BinaryNode<?> node: nodes) {
            sum += height(node);
        }
        return sum;
    }
    

    如果您只能访问树结构中的节点:

    int sumHeight(BinaryNode<?> node) {
        if (node == null) return 0;
        return height(node) + sumHeight(node.left) + sumHeight(node.right);
    }
    

    看看是否有可以在一次递归中进行计算的算法会很有趣(也许是一些回溯算法?)。

    【讨论】:

    • 不需要回溯算法;只需在计算高度时将高度存储在地图中即可。
    【解决方案4】:

    好的。我已经找到了解决方案。

    a) 如果n == null 返回0

    b) 如果n.left == null &amp;&amp; n.right == null 返回0

    c) 总高度为total height of left + total height of right + the height of it self

    • 自身的高度为:

    1) 如果左侧较大,则左侧总高度减去左侧左侧总高度

    2) 如果右侧较大,则右侧总高度减去右侧右侧总高度

    public int totalHeight() {
        return totalHeight(root);
    }
    
    private int totalHeight(BinaryNode<AnyType> n) {
        if (n == null)
            return 0;
        else if (n.left == null && n.right == null)
            return 0;
        else
            return totalHeight(n.left)
                    + totalHeight(n.right)
                    + (totalHeight(n.left) > totalHeight(n.right) ? totalHeight(n.left)
                            - (n.left == null ? 0 : totalHeight(n.left.left))
                            : totalHeight(n.right)
                                    - (n.right == null ? 0
                                            : totalHeight(n.right.right))) + 1;
    }
    

    【讨论】:

      【解决方案5】:

      我假设您在插入过程中没有更新高度。

      解决方案: 我会以一种无序的方式遍历树。所以我先声明root.height=0。

      然后说

      BinaryNode right;
      BinaryNode left;
      BinaryNode parent;
      static int level;
      int height;
      
      
      if(left!=null)
      {
          left.height=left.parent.height+1;
          level=level+left.height;
          left.yourMethod();
      }
      
      if(right!=null)
      {
          right.height= right.parent.height+1; 
          level=level+right.height;
          right.yourMethod();
      }
      

      所以您现在将拥有存储所有高度的关卡。

      替代方法可以是使用队列的广度优先搜索遍历,但答案是一样的。 希望这会有所帮助。

      【讨论】:

        【解决方案6】:

        void addHeights(class tree* root, int depth, int& sum) { 如果(根) { addHeights(root->left, depth+1, sum);
        addHeights(root->right, depth+1, sum); 总和 += 深度; } }

        【讨论】:

          【解决方案7】:
          public int sum(){
              return sum(root);
          }
          private int sum(BinaryNode <?> n){
              if(n == null)
                  return 0;
              else
                  return n.data + sum(n.left) + sum(n.right);
          
          }
          

          虽然我假设您将节点内的数据称为“数据”,但我需要更多数据来评估您的代码。

          因此,如果节点为空,则表示您已到达树的末尾并返回 0。否则,它将获取数据并先向左然后向右遍历。每次递归都会添加它们,直到没有更多节点可以添加。

          【讨论】:

            【解决方案8】:
             private  int maxHeight(BinaryNode<AnyType> n) {
              if (n ! = null) return 0;
              int leftheight = maxHeight(n.left);
               int rightheight = maxHeight(n.right);
              return (leftheight > rightheight) ? leftheight + 1 : rightheight + 1;
            }
            

            到目前为止,你已经知道了4种计算高度的情况

            本质是如果左孩子或右孩子存在,则继续向左或向右节点。 如果存在,则返回 1。

            计数函数在最后一条语句中。那就是计算最大的高度。

            主要课程是在方法工作时熟悉递归和编程堆栈。

            【讨论】:

            • 我想你误解了我的问题,我想得到所有节点高度的总和而不是找到树的高度。
            • 如何输入参数为left child,right child,然后将所有的高度结果相加?
            猜你喜欢
            • 2012-10-10
            • 2015-03-01
            • 2019-05-18
            • 2018-09-16
            • 2021-09-30
            • 1970-01-01
            • 1970-01-01
            • 2021-02-19
            • 1970-01-01
            相关资源
            最近更新 更多