什么才是真正的尾递归--各位大侠高手赐教
最近看数据结构书
发现清华的一本书上讲的尾递归概念不是很明确
便上网搜索下资料,却发现了不同的答案
清华的那本书上讲 如下这个例子就是尾递归
还有C PREMIR PLUS上也是这样的例子
求N!
int fun(n)
{
int f;
if(n==1) f=1;
else f=fun(n-1)*n;
return f;
}
但是网上查到的资料来看 以上2书的并不是真正的尾递归
////////////////////////////////资料如下/////////////////////////
下面用常见的计算n!的两种递归算法分析
线性递归:
long Rescuvie(long n) {
return (n == 1) ? 1 : n * Rescuvie(n - 1);
}
尾递归:
long TailRescuvie(long n, long a) {
return (n == 1) ? a : TailRescuvie(n - 1, a * n);
}
long TailRescuvie(long n) {//封装用的
return (n == 0) ? 1 : TailRescuvie(n, 1);
}
当n = 5时
对于线性递归, 他的递归过程如下
Rescuvie(5)
{5 * Rescuvie(4) }
{5 * {4 * Rescuvie(3) }}
{5 * {4 * {3 * Rescuvie(2) }}}
{5 * {4 * {3 * {2 * Rescuvie(1) }}}}
{5 * {4 * {3 * {2 * 1}}}}
{5 * {4 * {3 * 2}}}
{5 * {4 * 6}}
{5 * 24}
120
对于尾递归, 他的递归过程如下:
TailRescuvie(5)
TailRescuvie(5, 1)
TailRescuvie(4, 5)
TailRescuvie(3, 20)
TailRescuvie(2, 60)
TailRescuvie(1, 120)
120
很容易看出, 普通的线性递归比尾递归更加消耗资源, 在实现上说, 每次重复的过程
调用都使得调用链条不断加长. 系统不得不使用栈进行数据保存和恢复.而尾递归就
不存在这样的问题, 因为他的状态完全由n 和 a 保存.
////////////////////////////////资料结束/////////////////////////
显然上面2书的说法是线性递归而不是尾递归;
资料中的尾递归就是一个线性迭代的过程,
但我们知道函数在调用的时候都要先开辟属于自己的堆栈啊,
尾递归怎么就能例外呢(编译器优化??),
哪位高人给我讲讲,万分感谢!!!