递归算法相关总结

 

相信大部分人都知道,递归算法具有容易理解、结构清晰等优点,但是和非递归方法相比无论是空间需求还是时间需求一般来说都更高。其原因为:递归方法在运行时需要较多次数的函数调用,如果调用层数比较深,需要增加额外的堆栈处理,造成较大的空间需求;又参数传递时需要压栈等操作,造成时间需求比较高。

 

问题的提出:

1、递归算法有没有对递归层次的限制?

2、递归算法一定比非递归算法慢吗?究竟该选择哪种算法?

3、递归算法向非递归算法转化有哪些方法?

 

问题的解决:

1、在采用递归算法时,一定要注意递归的层次不能太深,请看下面的示例:

程序一:

public class TestRecursion{ public static void main(String args[]){ System.out.println(sum(100000000)); } public static long sum(int n){ long result=0; for(int i=1;i<=n;i++){ result=result+i; } return result; } }

程序二:

public class TestRecursion1{ public static void main(String args[]){ System.out.println(sum(10000)); } public static long sum(int n){ long result=0; if(n<0){ System.out.println("error"); }else if(n==1){ result=1; }else{ result=sum(n-1)+n; } return result; } }

分析:上面两个程序的功能都是计算出从1一直加到n的和,但是运行上面两个程序你会发现程序一即使运算一亿次也会顺利的计算出你想要的结果,而程序二连计算一万次的能力都没有。这是为什么呢?很简单,程序一只是在一次函数调用中利用一个for循环语句完成运算,虽然运算的次数多,但是对堆栈空间没有过多要求;程序二需要更多的堆栈空间,最终导致不能有太多层次的函数递归调用。如果你的程序需要很多次递归才能完成需求的话,一定要考虑能否顺利实现。

 

2、递归算法不一定比非递归算法慢,关键还要看具体的算法是什么,请看示例:

程序三

public class TestRecursive { public static void main(String[] args){ long t1=System.currentTimeMillis(); getMaxDivisor1(65464642,879797968); long t2=System.currentTimeMillis(); System.out.println("非递归所用时间"+(t2-t1)); long t3=System.currentTimeMillis(); getMaxDivisor2(65464642,879797968); long t4=System.currentTimeMillis(); System.out.println("递归所用时间"+(t4-t3)); } //非递归算法计算两个数的最大公约数 public static int getMaxDivisor1(int a, int b) { int max = 0; int temp = Math.min(a, b); for (int i = temp; i > 0; i--) { if (a % i == 0 && b % i == 0) { max = i; break; } } return max;// 当max为0时,即没有最大公约数 } // 递归算法计算两个数的最大公约数 public static int getMaxDivisor2(int a, int b){ if(Math.min(a, b)==0){ return Math.max(a, b); }else{ return getMaxDivisor2(Math.min(a, b), Math.max(a, b)%Math.min(a, b)); } } }

分析:执行上面的程序,观察执行结果,并将函数参数变一下多试几次。此程序的目的是向大家演示此处的递归算法比非递归算法有着相当快的执行速度,当然此程序中的两个算法采用的是完全不同的思路,如果将此处的递归算法转换为对应的非递归算法并不是此程序中所示的非递归算法那样的。这里主要是告诉大家,算法的好坏一定要根据其本质来判断,即根据时间复杂度和空间复杂度来判断,递归算法不一定比非递归算法慢,不能根据算法所属类型来判断好坏。

 

3、递归算法向非递归算法的转换

什么时候需要转换?

(1)当非递归算法在运行空间和执行效率上的确比递归算法要高很多时;

(2)有些语言不支持递归方法调用,此时需要转换;

转换的方法?

如果这里要详细的阐述转换的方法需要大量的篇幅,读者朋友可以看一下这两篇文章,我在这里就不在赘述;

1http://ppju.javaeye.com/blog/493141

2、江西师范大学计算机信息工程学院杨庆红、罗坚的论文

 

你可能感兴趣的:(算法,String,Class,语言)