二叉树 - 查找节点数k深度

时间:2011-02-03 21:34:37

标签: c tree binary-tree

以下函数在二叉树上运行。该函数将获取指向树根的指针和非负int 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);
}

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

5 个答案:

答案 0 :(得分:3)

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

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

该算法非常简单 - 在纸上绘制测试树并逐步完成。逻辑应该很快就会向你跳出来。

答案 1 :(得分:1)

理论上,给定深度处的节点总数(假设深度= 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 

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

答案 2 :(得分:1)

只是递归地想一想......

一个子树中有多少个节点,其中roor为null0

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 :(得分:0)

描绘一幅如何运作的图片......

想想你是否有这个小组执行任务,并且有这些隧道继续向两个子通道分叉。我们的目标是找出这么多的叉子,这些叉子可以通向一个洞穴。货叉之间的距离是一个长度单位。

每当你到达隧道中的一个分支时,该分支的当前组将分成两半并将每一半分别发送到两个子通道。

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

他们将总数加起来并向您汇报。

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

答案 4 :(得分:0)

单独理解这一行是不可能的,因为函数是递归的,而且一行是递归的那一行

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

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

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

前两个可执行行

如果我们从叶子节点向下遍历到空节点,我们只返回0.如果我们发现自己处于正确的深度,我们可以阻止任何无意义的遍历在树中并且只返回1,因为我们的实例递归函数已落在目标深度的单个节点上。这条线阻止我们不必要地穿越,以及为我们所在的分支提供计数。

最后一行

最后,你的最后一行。在每个更浅的层次上,有必要深入到树中,并且在递归实现中通过为树的每个分支调用函数的新实例来完成。该行可以由被调用实例再次执行,直到调用图本身累积镜像实际树,并且每个级别将更大的合并总和返回到先前级别,最终从单个实例返回单个可能相当大的数字。顶级节点。

相关问题