2013.8.8递归

  在功能(方法中)直接、间接调用了功能(方法)本身。

递归的优点:

  业务问题解决的很优雅,只需解决一个层次,其他层次问题就递归解决了。

递归的缺点:

  大量消耗栈内存空间,不能进行过深层次的递归,否则可能出现栈溢出错误。

使用递归要点:

  1. 不能过深的递归
  2. 不能发散递归(如果返回的值超过一个自己,例如f(n-1)+f(n-2)就是两个自己)
  3. 必须有初始返回值和结束条件

例如求斐波那契数列:1 1 2 3 5 8 13 21 34...,从第三项开始是前两项的和:

 1 /**
 2  * 用递归求斐波那契数列
 3  * f(n) = f(n-1) + f(n-2)
 4  * */
 5 public class Test {
 6     public long f(long n){
 7         if(n==0||n==1){
 8             return 1;
 9         }
10         return f(n-1) + f(n-2);
11     }

要求f(5)→f(4)→f(3)→f(2)

                    →f(1)

              →f(2)

        →f(3)→f(2)

              →f(1)

f(5)要知道f(4)和f(3),而f(4)又要知道f(3)和f(2),f(3)要知道f(2)和f(1),从上图可以看到有很多重复的运算,并且产生很多中间变量,占用内存。

递归的性能非常低,当n等于50的时候就已经运算慢的不行了,下面是递归和for循环代码比较:

 1 package TestCode;
 2 
 3 import java.util.Arrays;
 4 /**
 5  * 用递归求斐波那契数列
 6  * f(n) = f(n-1) + f(n-2)
 7  * */
 8 public  class Test {
 9     public static long f(long n){
10         if(n==0||n==1){
11             return 1;
12         }
13         return f(n-1) + f(n-2);
14     }
15     public static long forDemo(long n){
16         long f1=1,f2=1,fn=1;
17         for(int i=3;i<n;i++){
18             fn = f1+f2;
19             f1 = f2;
20             f2 = fn;
21         }
22         return fn;
23     }
24     public static void main(String[] args) {
25         long t1 = System.nanoTime();//记录当前时间赋给t1,以纳秒为单位
26         Test.f(50);//调用递归函数求斐波那契数列第50项的值
27         long t2 = System.nanoTime();
28         Test.forDemo(50);//调用for循环函数求斐波那契数列第50项的值
29         long t3 = System.nanoTime();
30         System.out.println("递归调用需要时间"+(t2-t1)+"纳秒");//递归调用需要时间352421312762纳秒
31         System.out.println("使用for循环函数需要时间"+(t3-t2)+"纳秒");//使用for循环函数需要时间33240纳秒
32     }
33 }

 

 

posted on 2013-08-08 19:59  提子呀呀  阅读(215)  评论(0编辑  收藏  举报

导航