【问题标题】:Binary Tree -- Finding the number of nodes k depth二叉树——求节点数 k 深度
【发布时间】:2011-06-20 23:46:43
【问题描述】:

以下函数对二叉树进行操作。该函数将接收一个指向树根的指针和一个非负整数 k。它应该从根返回 k 深度的节点数。

struct treenode {
  int data;
  struct treenode* left;
  struct treenode* right;
}

int numNodesHeightK(struct treenode* root, int k){
  if(root == NULL) return 0; //if the tree is empty return 0
  if(k == 0) return 1; //if k = 0, then the root is the only node to return 

  //How does this statement work?
  return numNodesHeightK(root->left, k-1) + numNodesHeightK(root->right, k-1);
}

如果有人能解释一下最后陈述的逻辑。我没有看到那行代码如何返回正确的深度。

【问题讨论】:

    标签: c tree binary-tree


    【解决方案1】:

    不可能孤立地理解一行,因为函数是递归的,而这一行是递归的

    但是只有三行,所以我们可以很容易地理解整个事情。

    为了计算给定深度的节点,有必要遍历树直到该深度。

    这意味着我们递归地获取每个左右分支。

    前两个可执行行

    如果我们从叶节点向下遍历到空节点,我们只返回 0。如果我们在正确的深度找到自己,我们可以停止在树中进一步向下遍历并返回 1,因为我们的实例递归函数已落在目标深度的单个节点上。这条线可以防止我们不必要地深入遍历,并为我们所在的分支提供计数。

    最后一行

    最后,你的最后一行。在每个更浅的级别,都需要深入到树中,并且在递归实现中,通过为树的每个分支调用函数的新实例来完成。这条线可以由被调用的实例再次执行,直到调用图本身累积地反映了实际的树,并且每个级别返回越来越大的合并和到之前的级别,最终从单个实例返回一个可能非常大的数字顶部节点。

    【讨论】:

      【解决方案2】:

      只是递归地想它......

      根为null 的子树中有多少个节点? 0

      if (root == NULL) return 0;
      

      深度为 0 的节点下有多少个节点? 1(节点本身)。

      if (k == 0) return 1;
      

      否则一棵树有多少个节点和子节点?左侧分支上的节点加上右侧分支上的节点。每个分支都处于较低级别。

      // left side
      numNodesHeightK(root->left, k-1) +
      // right side 
      numNodesHeightK(root->right, k-1)
      

      【讨论】:

        【解决方案3】:

        描绘一下这是如何工作的......

        假设您有这个小组执行任务,并且这些隧道不断分叉到两个子隧道。我们的目标是在经过这么多岔路口后找出哪个子隧道通向洞穴。叉子之间的距离是一个距离单位长。

        每当您到达隧道中的一个分叉时,该分支的当前组就会分成两半,并将每一半发送到两个子隧道。

        每当小组分裂 K 次时,他们就会停下来查看位置。然后他们回到地面,每个人都告诉他是否找到了离入口有 k 距离的房间。如果任何一个小队在距离 k 之前到达死胡同,他们会返回并说没有空间。

        他们将总数相加并向您报告。

        房间是节点。分叉是每个节点的子节点。子团队是堆栈上您的方法的调用。

        【讨论】:

        • 实际上,机器实际上是派一个人来回遍历每个节点,呈锯齿形扇形。如果你有多个线程,那更像是一个团队分裂。
        【解决方案4】:

        理论是给定深度(假设深度 = 5)的节点总数与从左孩子和右孩子计算的深度 = 4 的节点的总和相同。 (因为移动到一个孩子已经引入了 1 的深度)。

        那么,让我们找出左子节点深度 4 的节点数:

        numNodesHeightK(root->left, k-1)
        

        以及右子节点深度4的节点数:

        numNodesHeightK(root->right, k-1)
        

        将它们加在一起得到答案,从我们当前的节点得到深度5的节点数。

        仅此一项并不能解决问题,它只是将其分解为两个更简单、更小的部分。直到您询问深度 0 处的节点数(显然是 1),问题才完全解决。这是在函数的 基本情况中实现的:

        if(k == 0) return 1; //if k = 0, then the root is the only node to return 
        

        最后,您可以互换使用术语“高度”和“深度”,如果您尝试谈论“向下”或“向上”树,这会让人感到困惑。选择一个约定并坚持下去。

        【讨论】:

        • 嗨,如果我们要找到树中“高于”深度 k(不包括 k)的节点数该怎么办,如果 depth(n)
        【解决方案5】:

        对于每个节点,您希望将每个子树中深度 k 的节点数相加。这意味着从它们各自的根(当前节点的左右子树)遍历深度为k-1 的节点的子树。当k 到达0 时,这意味着为该节点返回1 - 因为它是来自原始根的深度k

        最后一条语句正是执行此操作 - 首先遍历左子树,然后遍历右子树,从当前节点查找深度为 k 的节点数,将它们相加,然后返回结果。

        该算法非常简单——在纸上画一个测试树并逐步完成它。逻辑应该很快就会跳出来。

        【讨论】:

        • 我还要指出这是一个递归算法;能够理解此示例将有助于 OP 理解许多其他示例。
        • +1 @Santa - 好电话。 OP 也应该检查“深度优先搜索”。
        猜你喜欢
        • 1970-01-01
        • 2020-07-19
        • 2020-10-24
        • 2021-01-02
        • 1970-01-01
        • 1970-01-01
        • 2015-06-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多