内存堆栈如何寻找背靠背递归调用?

时间:2016-08-21 00:22:37

标签: java recursion

我试图理解递归的概念。如果代码中有一个递归语句(例如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语句?

2 个答案:

答案 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),并为leftright调为0,结果为{ {1}}。

如果您将前一个节点绑定到变量0 + 1并尝试node,它将同时执行getDepth(new Node(node, node))left,其中两个都是{之前的测试1.结果为right,因此为2.

您可以像这样继续,并根据之前的计算假设结果。通过从复杂的参数看,你需要想象每个连续的递归都是以它的参数开始新的,并且遵循相同的模式。传回结果后,调用者继续到下一行。在树结构中:

1 + 1

我只是对节点编号而不包括空节点。您将看到执行按此顺序执行。标识表示堆栈深度/等待恢复的呼叫数。

     1
    / \
   2   3
  /\   /\
 4  5 6  7