递归有两个阶段:递推与回归。
递推:在递推阶段每一个递归调用通过进一步调用自己来记住这次递归过程。当其中有调用满足终止条件时,递推结束。
回归:函数调用已逆序的方式回归,直到最初调用的函数返回为止,此时递归过程结束。
基本上来说,一个程序由4个区域组成:代码段、静态数据区、堆与栈。代码段包含程序运行时所执行的机器指令。静态数据区包含在程序生命周期都一直存在的数据,不如全局变量和静态局部变量。堆包含程序运行时动态分配的空间,比如malloc。栈包含函数调用的信息。如下图所示:
下面是一个使用递归计算阶乘的例子:
int fact(int n){ if (n < 0) { return 0; } else if (n == 0 || n == 1) { return 1; } else { return n * fact(n - 1); }}为了解决普通递归需要相当大的空间来保存函数信息,提出了尾递归的递归方式。
当递归调用是整个函数中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归的。
当编译器检查到一个函数是尾递归的时候,它就会覆盖当前活跃记录而不是在栈中去创建一个新的,这样就解决了普通递归函数占用栈空间过大的问题。
使用尾递归修改上面的列子:
int facttail(int n, int a){ if (n < 0) { return 0; } else if (n == 0 || n == 1) { return a; } else { return facttail(n - 1, n * a); }}新闻热点
疑难解答