1.递归基本定义
递归的产生:某方法反复的调用自身。
2.递归的思考流程
第一步:找到f(n)与f(n-1)和f(n-2)的关系
第二步:找到终止条件,例如n==1时的情况
2.递归的缺陷
在递归的方法调用过程中,会将方法的(1)parametersand local variables(参数和本地变量);(2)Dynamic link(动态链接);(3)Return Address(返回地址);(4)Return Value(返回值)压入栈中,如下图所示
从上图中可以看出,当递归的函数量很大时,在运行时栈中则压入了大量的上述数据,最终导致栈溢出。为了解决上述问题,使用了“尾递归”。
3.尾递归
正常的递归中,函数都有返回值,这样就要把返回值压入栈中,在尾递归中,则将返回值以参数的方式传递,这样栈中只需保存一个函数信息,举例如下:
计算n*n-1*n-2*…*3*2*1
使用普通递归如下:
public int recursion(int i){
if(i==1)
return 1;
else
return i* recursion(i-1);
}
使用尾递归:
public int tailRecursion(int i,int acc){
if(i==1)
return acc;
else
returntailRecursion(i-1,i*acc);
}
尾递归将所得的结果放在参数acc中,
if(i==1)
return acc;
这里的acc即初始值。
来看看调用的结果
输入参数i=4,调用的函数依次为:
tailRecursion(4,1);
tailRecursion(3,4*1);
tailRecursion(2,4*3*1);
tailRecursion(1,4*3*2*1);
所以,不会将额外的信息压入栈中,只用将最后的一个函数压入栈中。
4.其他递归
间接递归:f()不是直接调用本身,而是通过一系列调用最终都调用自己,例如
f()->g()->h()->f()
嵌套递归:一个函数不仅仅定义成自己,而且用作参数,例如: