请考虑以下代码:
public int heightOfBinaryTree(Node node)
{
if (node == null)
{
return 0;
}
else
{
return 1 +
Math.max(heightOfBinaryTree(node.left),
heightOfBinaryTree(node.right));
}
}
我想知道这段代码背后的逻辑推理。人们是怎么想出来的?有些人有归纳证据吗?
此外,我想到只用二叉树的根作为参数获取二叉树的高度。以前的方法比我的好吗?为什么?
答案 0 :(得分:48)
if (node == null)
{
return 0;
}
叶节点的子节点为null
。因此,这就是说,一旦我们走过树叶,就没有其他节点了。
如果我们没有经过叶节点,我们必须计算高度,这个代码递归。
return 1 +
当前节点将高度1添加到当前正在计算的子树的高度。
Math.max(heightOfBinaryTree(node.left),
heightOfBinaryTree(node.right));
我们递归计算左子树(node.left
)和右子树(node.right
)的高度。由于我们正在计算最大深度,我们采用这两个深度的最大值。
我上面已经说明了递归函数是正确的。因此,在父节点上调用该函数将计算整个树的深度。
以下是来自this document的树高的图形表示。 h
是树的高度,hl
和hr
分别是左右子树的高度。
而且,我只想做一个 BFS与二叉树的根 作为获得高度的论据 二叉树。是以前的 比我的方法更好?为什么?
您提供的代码是DFS的一种形式。由于您必须处理所有节点以查找树的高度,因此DFS和BFS之间不存在运行时差异,尽管BFS将使用O(N)内存而DFS将使用O(logN)内存。 BFS的代码也稍微复杂一些,因为它需要一个队列,而DFS则使用“内置”递归堆栈。
答案 1 :(得分:4)
该代码背后的逻辑是:
因为一个节点将有两个孩子,树的高度将是树的高度的最大值,树的根是左子和右子,当然+1是步行给孩子。
如您所见,上面的描述是递归的,代码也是如此。
BFS也应该这样做,但实施和空间/时间复杂性都会过度。
有一种说法,递归函数虽然难以理解,但实现起来非常优雅。
答案 2 :(得分:2)
树的高度是从它的根开始的最长下行路径的长度。 此函数是一种递归方式来计算二叉树的级别。它只是在计数器下降树时递增计数器,返回最大计数器(最低节点上的计数器)。
我希望我有所帮助。
答案 3 :(得分:0)
这是一个递归函数。它说树的高度是1 +最高分支的高度。
BFS是第一次广泛搜索吗?我不确定效率会有什么不同,但我喜欢递归函数的简单性。
答案 4 :(得分:0)
对答案进行更多扩展,并详细说明递归加递归调用堆栈。
假设树
2
/\
5 9
/
0
让我们先假设左子树,root(2) 调用左子树上的 heightOfBinaryTree
方法
有问题的方法的调用栈如下
node(5) calls node(0)
node(0) calls node(null)
node(null) breaks the recursive loop
考虑到这些调用是在方法返回任何内容之前进行的。
返回递归调用堆栈,这是每个节点返回其输出的地方。
node(null) returned 0 -> 0
node(0) returned (return from node(null) + 1) -> 1
node(5) returned (return from node(0) + 1) -> 2
同样适用于右子树。如果我们比较左右子树的输出,我们就会得到高度。