【发布时间】:2013-03-07 20:03:34
【问题描述】:
几个月前开个玩笑,我的一位同事试图通过使用这种指数算法计算斐波那契数来“加速宇宙的热寂”:
int Fib(int n)
{
if (n <= 1)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
这如何不会导致 C# 中的堆栈溢出?我们在放弃之前设法到达了 Fib(52)(而 Fib(51) 花了很多时间)。我认为这会严重影响堆栈以导致堆栈溢出,因为默认情况下 CLR 仅分配 1M 给堆栈。另外,我很确定这也不符合尾递归的条件。
【问题讨论】:
-
那么,你认为每次递归有多少字节被压入堆栈?
-
您使用的是什么版本的 C# 编译器和框架?您是否查看过生成的 MSIL 或它得到 JIT 的 [de] 编译的汇编程序? C# 编译器完全有可能将解析树识别为斐波那契序列并进行特殊情况优化。
-
2^52 是我的超级天真计算,呵呵,因为复杂度是 O(2^n)
-
时间复杂度和空间复杂度不是一回事。该程序在堆栈空间中是 O(n),在时间上是 O(Fib(n))。 (关于 naive fib 的有趣之处在于,运行时间与输出的大小成正比。)
-
另外,您没有计算第 52 个 fib 数。第 47 位以上的 Fib 数大于 int.MaxValue。你无声无息地溢出。
标签: c# .net algorithm stack-overflow fibonacci