BST递归查找高度

时间:2013-11-14 00:16:51

标签: c++ recursion tree height binary-search-tree

我正在尝试在我的程序中找到二进制搜索树的高度,并继续使用这个递归解决方案来找到高度:

int maxHeight(BinaryTree *p) {
  if (!p) return 0;
  int left_height = maxHeight(p->left);
  int right_height = maxHeight(p->right);
  return (left_height > right_height) ? left_height + 1 : right_height + 1;
}

有人可以向我解释一下这是如何运作的吗?我不明白它是如何增加高度的。它看起来应该只穿过树的每一边并返回0。

3 个答案:

答案 0 :(得分:2)

算法以这种方式工作: 如果我正在查看的树不存在,那么树的长度为0。

否则,树的长度是我拥有的两个子树的最大高度加1(需要加1才能包含您当前正在查看的节点)。

E.g。如果我有一棵没有树枝的树(即树桩),那么我的高度为1,因为我有两个高度为0的子树,这些高度加上1的最大值为1.

另一个例子: 如果我有一棵树:

A - B - C - D
    |   |
    E   F

(其中a是root)

然后,高度不为0,因为A不为空

身高=最大(身高(左),身高(右))+ 1。

A处左边的高度为0,因为A没有左分支。

右分支的高度是B + 1的高度。

计算出B的高度,我们认为B是一棵全新的树:

B - C - D
|   |
E   F

现在 height = max(height(left),height(right))+ 1。

为了解决左派的问题,我们将E视为一棵全新的树:

E

这是因为它的高度不是0

然而,它的两个分支不存在,所以它的高度为1(每个分支的高度为0)

再次回到父树:

B - C - D
|   |
E   F

我们正在计算高度,发现左侧分支的高度为1。

所以height = max(1,height(right))+ 1

那么,右边的高度是多少?

再一次,我们认为正确的分支是它自己的树:

C - D
|
F

问题与以前一样 height = max(height(left),height(right))+ 1

计算出高度(左),我们自己考虑F

˚F

F的高度为1,因为它有两个空分支(即最多两个0高度加1)

现在正确看

d

出于同样的原因,D的高度为1

回到F和D的父母:

C - D
|
F

C的高度为:

max(高度(F),高度(D))+ 1

= max(1,1)+ 1

= 1 + 1

= 2。

所以现在我们知道C的高度,我们可以回到父母:

B - C - D
|   |
E   F
回想一下,我们把B的左分支的长度计算为1,然后开始计算它的右分支高度。

我们现在知道右分支的高度为2

最大值(1,2)为2。

2 + 1 = 3

因此,B的高度为3。

现在我们知道了,我们终于回到原来的树了:

A - B - C - D
    |   |
    E   F

我们已经计算出左侧分支高度为0,然后开始处理右侧分支。

我们现在知道右分支的高度为3。

因此,     height(a)= Max(height(null),Max(height(B))               =最大(0,3)+ 1               = 3 + 1               = 4

完成。 A的高度为4。

答案 1 :(得分:0)

如果二叉树为空,则该函数仅返回0。这是有道理的,因为如果树为空,则没有要计数的节点,因此高度为0.

如果它不为null,则该函数将向左或右子子树的高度添加1(当前节点的高度),以较大者为准。

它如何知道子子树的高度?通过调用自己递归传递左子项或右子项,以便下一次递归在树中向下开始一级。

第一次在树的根中调用函数时会发生什么?该函数首先调用自身递归地向下移动最左边的子节点,直到它找到叶节点。它再次调用自己传递叶子节点的左子节点,它是null。最后一次调用不再递归,只返回0.函数然后递归到叶子的右子项,它也返回0.然后它为自己的高度加1并返回。

我们现在处于最左边的叶子的父母,并且像以前一样将它递归到正确的孩子(兄弟到叶子)。那个可能不存在(返回0),是叶子(返回1)或有子节点(返回> 1)。无论返回值是什么,它都将与最左边的叶子(高度1)进行比较,以较大者为单位递增(总是添加当前节点的高度)并返回为以当前节点为根的子树的高度节点

请注意,递归将继续“展开”,因为它会返回到根,但在每个级别,它将首先递归到右子子树。这就是所谓的深度优先搜索。最终,将访问整个树,并且突出的最大高度一直计算回根。

答案 2 :(得分:0)

您的代码不符合内存。例如,运行此方法时,height_leftheight_right变量仍将保存在内存中。那么,如果你运行这个功能数十亿次呢?我建议不返回任何变量,例如

return max(maxHeight(p->left), maxHeight(p->right));