标签:long 内存 特性 数据 占用 star over test ack
1、递归的定义
2、递归的适用场合
3、线性递归
也就是普通递归,下一次递归数据的计算要依赖于上一次递归的结果和参数,当数据量较小时执行效率与尾递归几乎没区别,但当数据量较大,迭代次数较多时,由于每次递推都要在内存中开辟一个栈空间,用来存储上次递推的结果和参数,这样的算法将导致严重的内存开销,甚至造成内存溢出,抛出java.lang.StackOverflowError,下面用线性递归实现斐波那契数列。
/**
* 线性递归实现斐波拉契数列
* @param month
*/
public int fblq(int month){
if(month<3){
return 1;
}
return fblq(month-1)+fblq(month-2);//每步递推都严重依赖上一次递推结果,并占用大量的栈区空间,执行效率极低
}
测试上段程序运行时间
@Test
public void test(){
long startTime = System.currentTimeMillis();
System.out.println(fblq(50));
long endTime = System.currentTimeMillis();
System.out.println("程序运行时间:" + (endTime - startTime) + "ms"); //输出程序运行时间
}
程序运行时间:43643ms(非常慢),递推所需栈区空间,以指数级进行增长
4、尾递归
如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个函数是尾递归的。尾递归函数的特点是在回归过程中不用做任何操作,这个特性很重要,因为大多数现代的编译器会利用这种特点自动生成优化的代码。
/**
* 斐波那契数列尾递归
*/
public int fblq(int n,int num1,int num2){
if(n==1){
return num1;
}
return fblq(n-1,num2,num1+num2);
}
@Test
public void Test37(){
long startTime = System.currentTimeMillis();
System.out.println(fblq(50,1,1));
long endTime = System.currentTimeMillis();
System.out.println("程序运行时间:" + (endTime - startTime) + "ms"); //输出程序运行时间
}
程序运行时间:1ms,递归以线性关系增长
总结:在能使用尾递推时尽量使用尾递推,这样不仅能节省内存资源,而且执行效率更高,但是相比于普通for循环,递推的效率是较低的,所以再不是非递推不可的环境中,尽量使用普通循环代替递归算法。
标签:long 内存 特性 数据 占用 star over test ack
原文地址:http://www.cnblogs.com/gongli123/p/6925278.html