递归调用中的执行顺序

Order of execution in a recursive call

当一个return命令有两个递归调用时,例如 return fib(n-1) + fib(n-2);,两个调用是同时执行,还是fib(n-1)先于fib(n-2)执行?

通过使用记忆化,时间复杂度降低到 O(n),但只有在 fib(n-2) 之前执行 fib(n-1)(然后使用存储的值)才可能吗?

*public int fib(int n)是一种使用递归计算第N个斐波那契数的方法。

Java guarantees 表达式中子表达式的求值顺序是从左到右。

The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.

这意味着 fib(n-1) 将在 fib(n-2) 之前计算。

但是评估顺序并没有改变这里记忆的复杂性,无论哪种方式,它仍然是 O(n)。在 Java 对其求值时,fib(n-1) 将完成 n-1 之前的所有备忘录值,包括 fib(n-2) 的值。调用 fib(n-2) 没有任何作用;它只是引用了已经计算出的值 fib(n-1)

如果你颠倒了代码中的顺序:

fib(n-2) + fib(n-1)

然后将首先调用fib(n-2),这将完成通过n-2的所有备忘录值。然后调用 fib(n-1) 将使用现有的记忆值 "finish the job" 通过 fib(n-1).

完成所有值

无论哪种方式,在评估这些表达式之后,通过 n-1 的所有值都被记忆,具有 O(n) 的(最坏情况)时间复杂度(和 space 复杂度)。也可能这是调用 fib(n) 的结果,它会额外记住 n.

的值