繁体   English   中英

二叉树—查找深度为k的节点数

[英]Binary Tree — Finding the number of nodes k depth

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

如果有人可以解释最终声明的逻辑。 我没有看到那行代码如何返回正确的深度。

对于每个节点,您希望将每个子树在深度k处的节点数量加在一起。 这意味着遍历距离其各自根深度为k-1节点的那些子树(当前节点的左右子树)。 k变为0 ,这意味着对该节点返回1 ,因为它距原始根的深度为k

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

该算法非常简单-在纸上绘制测试树并逐步进行测试。 逻辑应该很快就向您跳来。

从理论上讲,给定深度(例如,depth = 5)的节点总数与从左子代和右子代计算得出的深度= 4的节点总和相同。 (因为移入孩子已经引入了深度1)。

因此,让我们在左子节点上找到深度4处的节点数:

numNodesHeightK(root->left, k-1)

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

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 

最后,您可以互换使用术语“高度”和“深度”,这在您尝试谈论使树“下”或“上”时会造成混淆。 选择一项惯例并坚持下去。

递归地考虑一下...

子树中roor为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)

画一下这是如何工作的...

想想像是您有这个小组在执行任务,并且有这些隧道将分叉到两个子隧道。 目的是找出经过这么多叉的子隧道,该子隧道打开了一个山洞。 货叉之间的距离为一个距离单位长。

每次到达隧道中的分支时,该分支处的当前组都会分成两半,并沿两个子隧道向下发送。

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

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

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

这是无法理解的隔离是一条线,因为该功能是递归的那一条线是递归的一个

但是只有三行,因此我们可以轻松地理解整个过程。

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

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

前两行

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

最后一行

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM