我碰到了这种算法,以发现二叉树的高度。有谁能够解释它是如何工作的?具体来说,我对max函数内部的递归调用感到困惑。每次迭代的最大比较值是多少?如何在不引起TypeError的情况下将输出加到1?谢谢!
def get_height(root):
if root is None:
return 0
return 1 + max(get_height(root.left), get_height(root.right))
答案 0 :(得分:2)
具体来说,我对max函数内部的递归调用感到困惑。每次迭代的最大比较值是多少?如何在不引起TypeError的情况下将输出加到1?
您要调用一个函数两次,并将这两个函数调用的返回值传递给max。因此,max正在比较此函数返回的结果。
如果不清楚,让我们分解一线:
left_height = get_height(root.left)
right_height = get_height(root.right)
max_height = max(left_height, right_height)
return 1 + max_height
由于我们要调用的函数始终返回一个整数,因此max会比较两个整数,这将为您提供两个整数中较大的一个。显然,我们可以加1。
换句话说,树的高度比任何一个子树的高度高1。
您可能认为我在那儿作弊。当我不得不假设该函数来证明它时,如何证明该函数始终返回整数?
关键在于递归是归纳的。如果您不太懂数学,那是一种很好的说法:
第一部分很简单:如果为None,则返回0。
第二部分来自树的定义:树的左分支和树的右分支始终是树的较小子树。 (对于循环图,root.left
可能是root
或其祖父母,这不是真的。)
第三部分是答案上半部分的解释。
我们完成了。
答案 1 :(得分:2)
在代码中添加一些行将有助于弄清发生了什么。
这里是表示树的类。
class Tree:
def __init__(self,id,left=None,right=None):
self.id = id
self.left = left
self.right = right
还有一个查找高度的函数。
def get_height(root):
if root is None:
return 0
my_height = 1 + max(get_height(root.left), get_height(root.right))
print("id :{} height: {}".format(root.id,my_height))
return my_height
t = Tree(1,Tree(2,Tree(4),Tree(5)),Tree(3))
t如下所示。
1
/ \
2 3
/ \
4 5
调用get_height(t)
时,输出如下:
id :4 height: 1
id :5 height: 1
id :2 height: 2
id :3 height: 1
id :1 height: 3
该调用从根开始,直到到达叶节点后,该函数将使用None
进行调用。
假设已经到达叶子(例如,节点4)。节点4上get_height()的结果为1 + max(get_height(None),get_height(None)) = 1 + max(0,0) =1
。
因此,节点4返回1。调用者(节点4的父节点,即节点2)将从1
获取Node 4
,并从1
获取Node 5
。
因此,它将得出结论,其高度为1+max(1,1)=2
并将该值返回给父节点。
以同样的方式,节点1(根)将从2
获得Node 2
,并从1
获得Node 3
,并将其高度计算为1+max(1,2)=3
。
树的高度为3,根为高度3。