几个月前,作为一个笑话,我的一位同事试图通过使用这种指数算法计算斐波纳契数来“加速宇宙的热死”:
int Fib(int n)
{
if (n <= 1)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
这怎么不会导致C#中的stackoverflow?我们设法在放弃之前得到了Fib(52)(而Fib(51)花了很多时间)。我认为这会严重破坏堆栈以导致堆栈溢出,因为CLR默认只将1M分配给堆栈。另外,我很确定这也不适合尾递归。
答案 0 :(得分:20)
递归调用不会同时计算,而是按顺序计算,这意味着Fib(n - 2)
只会在Fib(n - 1)
之后计算(或者相反)。这意味着即使您创建2^n
递归调用,也只会n
同时处于活动状态。因此,Fib(52)
只需52
Fib
个{{1}}堆栈帧的空间,不占用任何明显的堆栈空间。
答案 1 :(得分:2)
天真的Fibonacci实现确实会产生大量的函数调用(实际上等于结果),但它并没有非常深入地进行递归。最大递归深度为n
。