【问题标题】:A question on getting number of nodes in a Binary Tree关于获取二叉树中节点数的问题
【发布时间】:2010-05-07 22:11:22
【问题描述】:

给定树的根,我编写了两个函数(伪代码)来计算二叉树的节点数和树高。 最重要的是,二叉树以 First chiled/next 兄弟格式表示。

所以

struct TreeNode
{
  Object element;
  TreeNode *firstChild;
  TreeNode *nextSibling;
}

计算节点数:

public int countNode(TreeNode root)
{
     int count=0;
     while(root!=null)
     {
        root= root.firstChild;
        count++;
     }

      return count;
}

public int countHeight(TreeNode root)
{
     int height=0;
     while(root!=null)
     {
        root= root.nextSibling;
        height++;
     }

  return height;

}

这是我在算法书上看到的问题之一,我上面的解决方案似乎有一些问题,我也不太明白使用二叉树的第一个孩子/右兄弟表示的要点,你能请大家给我一些想法和反馈,好吗? 干杯!

【问题讨论】:

    标签: data-structures


    【解决方案1】:

    下一个兄弟和第一个孩子的使用大概可以这样可视化:

    A1 -- A2 -- A3
    |     |    
    |     B1 -- B2 -- B3
    |           |
    D1 -- D2    C1
    

    图中水平线代表nextSibling,垂直线对应firstChild链接。对于某些问题,这可能是自然的可视化(但对于其他一些问题,您可能更喜欢具有两个子节点的普通树 - 它们是等效的)。

    您的伪代码似乎缺少一些东西,因为您并没有真正计算任何东西。我想您想在while 循环中分别拥有count++height++

    无论如何,要计算节点数,您需要将孩子的节点数以及同一级别(兄弟姐妹)的节点数相加。对于相当小的树,这可以递归地完成:

    public int countNode(TreeNode root) { 
      if (root == null) return 0;
      return 1 + countNodes(root.firstChild) 
               + countNodes(root.nextSibling);
    }
    

    对于较大的数据结构,您需要将“待处理”节点存储在内存堆栈中以避免堆栈溢出(原文如此!)

    要计算高度,您首先需要确定如何定义高度。是您关注firstChild 链接时的路径(即A1 -> D1),还是您想要树中最长的路径(任何地方)(即A1 -> A2 -> B1 -> B2 -> C1)。在第一种情况下,您的实现将是正确的。在第二种情况下,您需要一个类似于计算节点的递归函数(而不是添加,而是选择较大的子树)。

    【讨论】:

    • 谢谢,Tomas,我真的意识到我的错误在哪里了。我只是拿起了两个分支中的一个而忽略了另一个,这太糟糕了!!
    【解决方案2】:

    虽然字面上是正确的,但“第一个孩子”和“右兄弟姐妹”可能有点令人困惑。如果换成“left child”和“right child”,我想你会理解得更好一些。

    【讨论】:

      【解决方案3】:

      要了解递归,首先必须了解递归。

      public int countNode(TreeNode root) 
      { 
           if (root==null) { 
              return 0;
           } else {
              return countNode(root.firstChild) + countNode(root.nextSibling) + 1;
           }
      }
      
      public int countHeight(TreeNode root) 
      { 
           if (root==null) { 
              return 0;
           } else {
              return max(countHeight(root.firstChild),
                         countHeight(root.nextSibling)) + 1;
           }
      }
      

      如果树为空,则它不包含节点并且没有高度。

      如果树不为空,则它比其更高的子树高一个节点,并且它包含两个子树的所有节点,加上包含两个子树的节点。

      阅读 Dave Touretzky 关于 LISP 的书。 Dave 用龙的故事来教授递归,而龙其实是一位很好的老师。

      【讨论】:

        猜你喜欢
        • 2021-09-30
        • 2018-11-25
        • 1970-01-01
        • 1970-01-01
        • 2022-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多