我试图理解递归的概念。如果代码中有一个递归语句(例如factorial)
,我理解它是如何工作的我不明白如何使用这样的代码来计算二叉树的深度:
public int getDepth(Node root)
{
if ( root == null) return 0;
int left = getDepth(root.left);
int right = getDepth(root.right);
if (left > right)
return left + 1;
else
return right + 1;
}
我知道为什么会这样,但不会如何。有人可以向我解释第二次递归调用(getDepth(root.right))是如何工作的吗?这段代码在内存中会是什么样子?当getDepth(root.left)被递归调用时,该堆栈是否会转到每个底部的if语句?
答案 0 :(得分:0)
如果树只包含一个节点(只是根节点),请尝试跟踪执行情况。
调用getDepth(root.left)
时,堆栈看起来像这样:
--->getDepth(root.left) //this will return 0 immediately, and will be popped of the stack
getDepth(root) // this is your entry point
一旦getDepth(root.left)
返回,堆栈看起来像这样:
--->getDepth(root) // this is your entry point
然后堆栈顶部的方法现在将继续执行它的位置(它现在将调用getDepth(root.right)
,堆栈将如下所示:
--->getDepth(root.right) //this will return 0 immediately, and will be popped of the stack
getDepth(root) // this is your entry point
再次,一旦getDepth(root.right)
返回,它将从堆栈中弹出,调用方法将继续执行,然后执行最后的if
语句。
对于具有多个节点的树,将遵循相同的执行模式:最终递归方法调用将返回(除非存在异常)并且调用方法将从下一个语句继续执行它。 / p>
答案 1 :(得分:0)
每次对getDepth
的连续调用都是完全独立的,因此绑定变量是独立的,它遵循它的参数,并且不知道它是从具有不同参数的自身版本调用的。
当你getDepth(null)
时,你得到0,因为它是第一行的基本情况。但是,如果您发送getDepth(new Node(null, null))
,则会调用与getDepth(root.left)
相同的getDepth(null)
,并为left
和right
调为0,结果为{ {1}}。
如果您将前一个节点绑定到变量0 + 1
并尝试node
,它将同时执行getDepth(new Node(node, node))
和left
,其中两个都是{之前的测试1.结果为right
,因此为2.
您可以像这样继续,并根据之前的计算假设结果。通过从复杂的参数看,你需要想象每个连续的递归都是以它的参数开始新的,并且遵循相同的模式。传回结果后,调用者继续到下一行。在树结构中:
1 + 1
我只是对节点编号而不包括空节点。您将看到执行按此顺序执行。标识表示堆栈深度/等待恢复的呼叫数。
1
/ \
2 3
/\ /\
4 5 6 7