fibonacci数列的不同实现方法对比(java)

来源:互联网 发布:数据结构与算法笔记 编辑:程序博客网 时间:2024/05/14 07:31

最近开始学习算法导论相关知识,了解到Fibonacci数列的不同实现,所以用java语言实现并进行测试,发现矩阵方式和从下向上计算(f(0),f(1),…, f(n))性能远远高于递归方式。
备注:可能代码质量不高,主要为了说明问题。其中没有对输入的Number采用更严谨的验证。


package com.demo;import java.util.Date;public class FibonacciNumbers {    /**     * @param number      * 最简单的递归调用,复杂度a^n,a为黄金分割点     * @return     */    public static long Fibonacci(int number) {        if (number == 0)            return 0;        if (number == 1)            return 1;        if (number >= 2)            return Fibonacci(number - 1) + Fibonacci(number - 2);        return -1;    }    /**     * @param number      * 时间复杂度为O(n) bottom algorithm     * compute F(0), F(1), ..., F(N)     * @return     */    public static long Fibonacci2(int number) {        long[] result = new long[number + 1];        if (number == 0)            return 0;        if (number == 1)            return 1;        if (number >= 2) {            result[0] = 0;            result[1] = 1;            for (int i = 2; i <= number; i++) {                result[i] = result[i - 1] + result[i - 2];            }        }        return result[number];    }    /**     * @param number >= 1      * 时间复杂度为O(logn)     * thm:[f(n+1), f(n); f(n), f(n-1)] = [1, 1; 1 0]^n     * @return     *///  private static long[][] prime = {{1, 1} ,{1, 0}};    public static long Fibonacci3(int number) {        Element result = FibonacciKernel(number);        if ( result != null) {            return result.b;        }        return -1;    }    public static Element FibonacciKernel(int number) {        if (number == 1) {            return new Element(1,1,1,0);        }        if (number >= 2) {            if (number % 2 == 0) {                Element e = FibonacciKernel(number/2);                // 为了访问方便,设置为共有属性                long a = e.a*e.a + e.b*e.c;                long b = e.a*e.b + e.b*e.d;                long c = e.c*e.a + e.d*e.c;                long d = e.c*e.b + e.d*e.d;                return new Element(a, b, c, d);            } else {                Element e = FibonacciKernel((number-1)/2);                long a = e.a*e.a + e.b*e.c;                long b = e.a*e.b + e.b*e.d;                long c = e.c*e.a + e.d*e.c;                long d = e.c*e.b + e.d*e.d;                // e*e*prime[1, 1; 1 0]                return new Element(a+b, a, c+d, c);            }        }        return null;    }    public static void main(String[] args) {        Date d1 = new Date();        System.out.println("45的递归算法结果: " + Fibonacci(45));        Date d2 = new Date();        System.out.println("总共消耗" + (d2.getTime() - d1.getTime()) + "ms");        System.out.println("45的非递归算法结果: " + Fibonacci2(45));        Date d3 = new Date();        System.out.println("总共消耗" + (d3.getTime() - d2.getTime()) + "ms");        System.out.println("45的矩阵方式计算结果: " + Fibonacci3(45));        Date d4 = new Date();        System.out.println("总共消耗" + (d4.getTime() - d3.getTime()) + "ms");    }}class Element {    long a;    long b;    long c;    long d;    public Element(long a, long b, long c, long d) {        this.a = a;        this.b = b;        this.c = c;        this.d = d;    }    public Element() {    }}

经过测试:

45的递归算法结果: 1134903170总共消耗19591ms45的非递归算法结果: 1134903170总共消耗0ms45的矩阵方式计算结果: 1134903170总共消耗0ms

发现后两种方式结果一样,但是理论上矩阵方式还是比非递归方式性能更高。

0 0
原创粉丝点击