斐波那契数列 Java 不同的实现方法所需要的时间比较

# 首先我们直接看一个demo以及他的结果

public class QQ {

    public static void main(String[] args) throws ParseException {

        // 1,1,2,3,5,8 ...
        int n = 50;
        Long start = System.currentTimeMillis();
        System.out.println(fun(n));
        System.out.println("time1 : " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        System.out.println(fun2(n));
        System.out.println("time2 :  " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        System.out.println(fun3(n));
        System.out.println("time3: " + (System.currentTimeMillis() - start));

    }

    public static long fun(int n) {
        if (n <= 2) {
            return 1L;
        } else {
            return fun(n - 1) + fun(n - 2);
        }

    }

    public static long fun2(int n) {
        if (n <= 2) {
            return 1L;
        } else {
            long a = 1, b = 1, c = 0;
            for (int i = 3; i <= n; i++) {
                c = a + b;
                a = b;
                b = c;
            }
            return c;
        }
    }

    public static long fun3(int n) {
        if (n <= 2) {
            return 1L;
        } else {
            long[] arr = new long[n + 1];
            arr[1] = 1;
            arr[2] = 1;
            for (int i = 3; i <= n; i++) {
                arr[i] = arr[i - 1] + arr[i - 2];
            }
            return arr[n];
        }
    }
}

# 上面代码的计算结果是:

12586269025
time1 : 46059
12586269025
time2 : 0
12586269025
time3: 0

# 分析:

  - 可以看出使用递归计算需要的时间最长

  - 我们不进行理论的分析,再用一个简单的例子去简要说明一下为什么递归需要的时间这么长

public class QQ {

    private static long count = 0L;

    public static void main(String[] args) throws ParseException {

        // 1,1,2,3,5,8 ...
        int n = 50;
        Long start = System.currentTimeMillis();
        System.out.println(fun(n));
        System.out.println("time1 : " + (System.currentTimeMillis() - start));
        System.out.println("count: " + count);

    }

    public static long fun(int n) {
        count++;
        if (n <= 2) {
            return 1L;
        } else {
            return fun(n - 1) + fun(n - 2);
        }

    }

}

# 上面代码的输出结果是:

12586269025
time1 : 48285
count: 25172538049

# 分析:
  - 可以看出fun这个函数被调用了很多次,但是这个函数基本上只有一个逻辑,我们来看看这个比较逻辑调用 25172538049 次会发生些什么吧

public class QQ {

    public static void main(String[] args) throws ParseException {

        // 1,1,2,3,5,8 ...
        int n = 50;
        Long start = System.currentTimeMillis();
        for (long i = 0; i < 25172538049L; i++) {
           
        }
        System.out.println("time1 : " + (System.currentTimeMillis() - start));
    }
}

# 上面代码的输出结果为:
time1 : 10358

# 分析:

  - 上面的代码循环中一共包含两个调用次数较多的逻辑;第一个是比较逻辑,第二个是 自增 逻辑, 可以看出,两个很简单的逻辑调用 25172538049 次就会耗时这么多,那么递归调用加上调用函数的各种开销,一共需要这么长的时间好像也就不足为奇了

 

posted on 2019-05-30 15:17  斜月三星一太阳  阅读(353)  评论(0编辑  收藏  举报