从入门开始手把手搭建千万级Java算法测试-斐波那契额数列的三种实现方法比较

  第八天开始呢,我们讲解斐波那契额数列的三种实现方法,从算法思路,到算法伪代码实现,到复杂度分析,从这里开始我们手把手搭建一个测试平台的基础,根据你自身硬件水平可以对下列代码进行从1000,到千万级测试,其中算法测试时间与你的机器硬件水平和实现的算法有关系,下面是斐波那契额数列的三种实现方法的具体讲解。
(1)排序算法的思路并且举例说明
用朴素递归算法计算Fibonacci数列;
用自底向上算法计算Fibonacci数列;
用分治算法计算Fibonacci数列;

(2)算法伪代码

//朴素递归:
Fibonacci(int n)
	If(n==1)
		Return 0
	If(n==2)
		Retuen 1
	N=Fibonacci(n-1)+ Fibonacci(n-2)
Return N
//自底向上:
Fibonacci(n)
A[0]=0
A[1]=1
For i=2 to n
	A[i]=A[i-1]+A[i]
Retuen A[n]
//分治法(矩阵):
Fibonacci ( A, n)
{
    w= {1,0,0,1};//初始二维矩阵
    q=w;
    if(n == 0){
     return q;
}
    else if(n ==1){
     return A;
	}
    else if(n%2==0){
     return change(Fibonacci (A, n / 2), Fibonacci (A, n / 2));
	}
    else{
     return change(change(Fibonacci (A, (n - 1) / 2), Fibonacci (A, (n - 1) / 2)), A);
	}
} 

(3)复杂度分析

1、 每个算法时间复杂度分析

(1)朴素递归
时间复杂度就是每一层递归的求和次数加和,易得1+2+4+8+2(k-1),再利用等比数列求和:和为:2(k-1) -1,其中k为n。当步长为2的时候,和为2^(n/2-1) -1用大O表示法表示代码的时间复杂度为O(2(n/2))到O(2n)之间。

(2)自底向上
使用了若干个辅助变量,迭代辗转相加,每次记录前一项,时间复杂度为 О(n),
但空间复杂度降到了 О(1)。

(3)分治法(矩阵)
斐波那契数列在n大于等于三的时候严格遵守递推数列f(n) = f(n-1) + f(n-2),而对于一个二阶的递推数列来说,我们可以用矩阵乘法来表示,且状态矩阵是2阶的方阵,由线代知识不难证明:2x2的矩阵 {1,1,1,0} ^ n = {Fn+1,Fn,Fn,Fn-1};因此,模仿"快速幂"算法得到以下:
(F(N),F(N-1))= (F(N-1),F(N-2))*A
不难分析时间复杂度为:O (lg n)

2.结论
分治法优于自底向上法优于朴素递归的方法。

(4)代码主体部分

package runoob;

public class Fibonacci {
    static long f1 = 1;//初始值
    static long f2 = 1;

    public static long Fibonacci_1(long count) {//递归
        long count2 = count;
        if (count2 == 0) {
            return f1;
        } else if (count2 == 1) {
            return f2;
        } else {
            return Fibonacci_1(count2 - 1) + Fibonacci_1(count2 - 2);
        }

    }
    public static long Fibonacci_2(long count) {//自底向上
        long next;
        long count1 = count;
        long a1 = f1;
        long b1 = f2;
        for (long i = 0; i < count1 - 1; i++) {
            next = a1 + b1;
            a1 = b1;
            b1 = next;
            //每五个换一行
        }
        return b1;
    }
    public static long[][] matrixMultiply(long[][] a, long[][] b) {
        int rows = a.length;
        int cols = b[0].length;//矩阵乘法的行宽列宽计算方式
        long[][] matrix = new long[rows][cols];

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                for (int k = 0; k < a[i].length; k++) {
                    matrix[i][j] += a[i][k] * b[k][j];
                }
            }
        }
        return matrix;
    }
    public static long Fibonacci_3(long count) {//分治法
        long count4 = count;
        if (count4 < 1) {
            return -1;
        }
        if (count4 == 1 || count4 == 2) {
            return 1;
        }
        long[][] result = {{1}, {0}};
        long[][] tem = {{1, 1}, {1, 0}};
        while (count4 != 0) {
            if ((count4 & 1) == 1) {
                result = matrixMultiply(tem, result);
            }
            tem = matrixMultiply(tem, tem);
            count4 >>= 1;//位右移
        }
        return result[1][0];
    }

    public static void Fibonacci_text(long num) {
        long count = num;
        System.out.println("计算个数共:"+num);
        long start = System.nanoTime();
        Fibonacci_1(count);
        long mid = System.nanoTime();
        System.out.println("递归法耗时为"+(mid-start)/1000+"ms");

        Fibonacci_2(count);
        long mid_2 = System.nanoTime();
        System.out.println("自底向上法耗时为"+(mid_2-mid)/1000+"ms");

        Fibonacci_3(count);
        long end = System.nanoTime();
        System.out.println("分治法耗时为"+(end-mid_2)/1000+"ms");
    }
}

  往期对应的代码中SortHelper类我们留一个小小的悬念,留到最后来进行叙说,其中目前来说他的方法generateRandomArray的参数为,(num,left,right)第一个参数参与算法生成的数量级,作为随机生成序列,它可以为千万,因为是long级别,left和right则为生成序列的大小范围,生成的序列为返回值类型为Integer[]。
(5)测试结果如下:

在这里插入图片描述
  本文重在算法讨论,所有不再展示结果,注重算法的运行时间,笔者有兴趣可以尝试千万级的算法测试,这里便不在赘述。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值