数据结构与算法

01-复杂度

2020-11-12  本文已影响0人  紫荆秋雪_文

铭记:

\color{#DC143C}{算法 + 数据结构 = 程序}

一、什么是算法

算法是用于解决特定问题的一系列的执行步骤

0、1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)

算法一:使用递归求和

    /**
     * 斐波那契数列(算法一)
     * @param index 下标位置
     * @return index 位置的数值
     * 下标:0、1、2、3、4、5、6、7、  8、 9、.... n
     * 数值:0、1、1、2、3、5、8、13、21、34
     */
    private static Integer fibonacci1(Integer index) {
        if (index < 2) {
            return index;
        }
        // 使用递归求和
        return fibonacci1(index - 1) + fibonacci1(index - 2);
    }

算法二:使用 for 循环求和(性能更高)

0、1、1、2、3、5、8、13、21、34、……n
n = 2 :F(2) = F(1) + F(0),循环1次
n = 3 : F(3) = F(2) + F(1),循环2次
n = 4 :F(4) = F(3) + F(2),循环3次
...
n :F(n) = F(n - 1) + F(n - 2),循环n-1次

    /**
     * 斐波那契数列(算法二)
     * @param index 下标位置
     * @return index 位置的数值
     * 下标:0、1、2、3、4、5、6、7、  8、 9、.... n
     * 数值:0、1、1、2、3、5、8、13、21、34
     */
    private static Integer fibonacci2(Integer index) {
        Integer first = 0;
        Integer second = 1;
        if (index < 2) {
            return index;
        }
        /**
         * 求index位置上的数值,其实就是求 index-1 和 index-2 位置上的数值之和
         *
         * 所以可以通过遍历来实现
         */
        Integer sum = 0;
        for (int i = 1; i < index; i++) {
            sum = first + second;
            first = second;
            second = sum;
        }
        return sum;
    }

算法二代码优化

    /**
     * 斐波那契数列(算法二)
     * @param index 下标位置
     * @return index 位置的数值
     * 下标:0、1、2、3、4、5、6、7、  8、 9、.... n
     * 数值:0、1、1、2、3、5、8、13、21、34
     */
    private static Integer fibonacci2(Integer index) {
        Integer first = 0;
        Integer second = 1;
        if (index < 2) {
            return index;
        }
        /**
         * 求index位置上的数值,其实就是求 index-1 和 index-2 位置上的数值之和
         *
         * 所以可以通过遍历来实现
         */
        for (int i = 1; i < index; i++) {
            second += first;
            first = second - first;
        }
        return second;
    }

测试算法

    public static void main(String[] args) {
        Integer n = 10;
        long startTime = System.currentTimeMillis();
        Integer integer = fibonacci1(n);
//        Integer integer = fibonacci2(n);
        long endTime = System.currentTimeMillis();
        long tiem = endTime - startTime;
        System.out.println("下标为 " + n + "的数据为:" + integer + " 用时:" + tiem);
    }
当n = 10时
算法一:下标为 10的数据为:55 用时:0ms
算法二:下标为 10的数据为:55 用时:0ms
当n = 20时
算法一:下标为 20的数据为:6765 用时:2ms
算法二:下标为 20的数据为:6765 用时:0ms
当n = 30时
算法一:下标为 30的数据为:832040 用时:42ms
算法二:下标为 30的数据为:832040 用时:0ms
当n = 40时
算法一:下标为 40的数据为:102334155 用时:1751ms
算法二:下标为 40的数据为:102334155 用时:0ms
当n = 48时
算法一:下标为 48的数据为:512559680 用时:62664ms
算法二:下标为 48的数据为:512559680 用时:0ms

二、算法的好坏

一般从以下纬度来评估算法的优劣

三、大O表示法

一般用大O表示法来描述复杂度,它表示的是数据规模 n 对应的复杂度

忽略常数、系数、低阶

注意:大O表示法仅仅是一种粗略的分析模型,是一种估算,能帮助我们短时间内了解一个算法的执行效率 时间复杂度大O表示法.png

斐波那契数列的时间复杂度

0、1、2、3、4、5、6、7、8、。。。n
0、1、1、2、3、5、8、13、21、34...

算法一的时间复杂度 算法一-时间复杂度1.png

算法一-时间复杂度2.png

算法二的时间复杂度

n = 2 :F(2) = F(1) + F(0),循环1次
n = 3 : F(3) = F(2) + F(1),循环2次

n = 4 :F(4) = F(3) + F(2),循环3次
...
n :F(n) = F(n - 1) + F(n - 2),循环n-1次

上一篇下一篇

猜你喜欢

热点阅读