java - 堆栈中将存储多少调用?

标签 java recursion stack fibonacci

有人可以解释一下下面的递归方法将在堆栈中存储多少次调用,为什么?什么时候存储在堆栈中?显然是 49 次调用,但我不明白为什么。谢谢。

public static long fib( int n ){ // n = 50
    if( n <= 1 )
        return 1;
    else
        return fib( n - 1 ) + fib( n - 2 );
    }

最佳答案

对于下面的递归方法,堆栈中将存储多少次调用,为什么?

输入为 50,在任何给定时刻,包括对 fib 的初始调用在内,堆栈帧的最大数量将为 50。(因此最多将存储 49 个递归调用堆栈在任何给定时刻)。

最多可以有 50 个栈帧的原因是:

fib(50) 的初始调用是 1 个堆栈帧。

然后用这个语句,return fib( n - 1 ) + fib( n - 2 ); 左边对 fib 的递归调用将首先执行,将 fib(49) 放入堆栈。我们将再次点击返回行,将 fib(48) 放入堆栈。这将重复,直到 fib(1) 在堆栈中命中 return 1; 语句。这将返回到 fib(2) 并允许在语句 return fib( n - 1 ) + fib( n - 2 ); 中执行正确的递归调用。

长话短说,所有左递归调用甚至在 1 个右递归调用执行之前执行。所以很容易看出您将拥有 fib(50)fib(49),...,最后是 fib(1)对于最后一个递归调用,在执行 fib(50); 时导致最多 50 个堆栈帧。

什么时候存储在堆栈中?

调用函数时,会分配一个栈帧,函数返回后,会释放栈帧。甚至 main 的函数调用也存储在堆栈中。然而,堆栈框架可能会被优化掉,但这是一个更高级的话题。

如果您想了解更多有关优化堆栈框架的信息,请参阅我小时候问过的这个问题:

Does a stack frame really get pushed onto the stack when a function is called?

补充编辑: 如果您想通过视觉了解递归是如何发生的,请将您的手指放在根的顶部,然后首先沿着左侧沿着树的外部追踪: enter image description here

关于java - 堆栈中将存储多少调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28711521/

相关文章:

java - 不打印堆栈中输入的第一个节点(toString)

Java 存储过程在 Oracle 数据库中不返回任何内容

c++ - 有效但没有多大意义的返回语句

Python在嵌套列表递归中获得第二小的值

stack - 为什么要使用面向堆栈的语言?

c++ - 在 Stack 实现中使用哪个智能指针?

java - 是否允许使用不同微服务中的相同表?

java - 无锁 CAS 混淆

java - 以编程方式更改 OSGi 包导入

java - 递归填充树