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

最近开始学习算法导论相关知识,了解到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
总共消耗19591ms
45的非递归算法结果: 1134903170
总共消耗0ms
45的矩阵方式计算结果: 1134903170
总共消耗0ms

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值