int Factorial( int number ) { if ( number == 1 ) { return 1; } else { return number * Factorial( number - 1 ); } }
除了慢 [1] 以及制作 使用运行时内存 不可预测的 [2] ,递归版本 这个例程很难 理解比迭代版本, 以下是:
int Factorial( int number ) { int intermediateResult = 1; for ( int factor = 2; factor <= number; factor++ ) { intermediateResult = intermediateResult * factor; } return intermediateResult; }
我认为缓慢的部分是因为不必要的函数调用开销。
但递归如何使运行时内存的使用变得不可预测?
我们不能总是预测需要多少内存(正如我们知道递归应该结束的时候)?我认为这与迭代案例一样不可预测,但现在不再存在。
答案 0 :(得分:3)
由于递归方法反复调用自身的事实,需要大量的堆栈内存。由于堆栈有限,如果超出堆栈内存,将发生错误。
答案 1 :(得分:1)
我们不能总是预测需要多少内存(正如我们知道递归应该结束的时候)?我认为这与迭代案例一样不可预测,但现在不再存在。
不,不是一般情况。有关更多背景信息,请参阅有关halting problem的讨论。现在,这里是其中一个问题的递归版本:
void u(int x) {
if (x != 1) {
u((x % 2 == 0) ? x/2 : 3*x+1);
}
}
它甚至是尾递归的。由于您无法预测这是否会正常终止,您如何预测需要多少内存?
答案 2 :(得分:0)
如果递归级别变得太深,那么你将会打破调用堆栈并在此过程中占用大量内存。如果您的number
是一个“足够大”的值,就会发生这种情况。你能做比这更糟糕的事吗?是的,如果你的函数在每次递归调用时都分配了更多的对象。