今天没事到公司,老毛病又犯了,到网上搜索一堆电子书来翻翻。
看到尾递归的概念,发现自己之前都没注意。
wiki上的说明:
在计算机科学里,尾调用是指一个函数里的最后一个动作是一个函数调用的情形:即这个调用的返回值直接被当前函数返回的情形。这种情形下称该调用位置为尾位置。若这个函数在尾位置调用本身(或是一个尾调用本身的其他函数等等),则称这种情况为尾递归,是递归的一种特殊情形。尾调用不一定是递归调用,但是尾递归特别有用,也比较容易实现。
尾调用的重要性在于它可以不在调用栈上面添加一个新的堆栈帧——而是更新它,如同迭代一般。尾递归因而具有两个特征:
而形式上只要是最后一个return语句返回的是一个完整函数,它就是尾递归。
尾递归在回归的过程中不用做任何操作,大多数的现在编译器会利用这种特点自动生成优化的代码,计算过程中,仅需要占用常量的堆栈空间(覆盖调用堆栈而不是创建新的)。
以计算阶乘为例,普通递归调用如下:
int fact(int n) { if (n < 0) return 0; else if (n == 0 || n == 1) return 1; else return n * fact(n - 1); }
由于最后一个步骤进行的是乘法的计算,不仅仅调用fact()函数,因此不是尾递归。
阶乘的计算过程可以表示为:
F(n, a) = |a 如果 n=0, n=1
|F(n-1, na) 如果 n>1
本质上,利用na迭代。
尾递归代码可以写为:
int facttail(int n, int a) { if (n < 0) return 0; else if (n == 0) return 1; else if (n == 1) return a; else return facttail(n - 1, n * a); }
原文:http://www.cnblogs.com/matteoxie/p/3617701.html