• 数据-第4课-审判程序的灵魂


    第4课-审判程序的灵魂

     

    1. 算法效率的度量

    l 事后统计法

    比较不同算法对同一组输入数据的运行处理时间.

    缺陷:

    (1) 为了获得不同算法的运行时间必须编写相应程序.

    (2) 运行时间严重依赖硬件以及运行时的环境因素.

    (3) 算法的测试数据的选取相当困难。

    事后统计法虽然直观,但是实施困难且缺陷多 ,但是实施困难且缺陷多,一般不予考虑。

    l 事前分析估算

    依据统计的方法对算法效率进行估算。

    l 影响算法效率的主要因素

    (1) 算法采用的策略和方法。

    (2) 问题的输入规模。

    (3) 编译器所产生的代码。

    (4) 计算机执行速度。

     

     

    算法效率的简单估算

     

     

     

     

     

    1. 算法效率的估量

    例子:二重循环估算

    #include <stdio.h>

    int func(int a[], int len)

    {

        int i = 0;

        int j = 0;

        int s = 0;

        for(i=0; i<len; i++)

        {

            for(j=0; j<len; j++)

            {

                s += i*j;

            }

        }   

        return s;

    }

    int main()

    {

        int array[] = {1, 2, 3, 4, 5};    

        printf("%d ", func(array, 5));    

        return 0;

    }

    估算时间:t = (n2 + 2) T

    启示

    (1) 练习中的程序关键部分的操作数量为n*n

    (2) 三种求和算法中求和的关键部分的操作数量分别为2n, n1

    随着问题规模n的增大,它们操作数量的差异也会越来越大,因此实际算法在时间效率上也会变得非常明显!

     

     

     

    不同算法操作数量的对比

     

     

    判断一个算法的效率时,往往只需要关注操作数量的最高次项,其它次要项和常数项可以忽略。

     

    O表示法

    (1) 算法效率严重依赖于操作(Operation)数量。

    (2) 在判断时首先关注操作数量的最高次项。

    (3) 操作数量的估算可以作为时间复杂度的估算。

    O(5) = O(1)

    O(2n + 1) = O(2n) = O(n)

    O(n2 + n + 1) = O(n2)

    O(3n3+1) = O(3n3) = O(n3)

    常见时间复杂度类型

     

     

    关系:O(1) < O(logn) < O(n) < O(nlogn) < o(n2) < O(n3) < O(2n) < O(n!) < O(nn)

     

    1. 最好与最坏

    例子:

    #include <stdio.h>

    int search(int array[], int length, int n)

    {

        int ret = -1;

        int i = 0;

        for(i=0; i<length; i++)

        {

            if( array[i] == n )

            {

                ret = i;

                break;

            }

        }   

        return ret;

    }

    int main()

    {

        int array[5] = {1, 2, 3, 4, 5};

        printf("%d ", search(array, 5, 1));  //O(1),一次就好

        printf("%d ", search(array, 5, 5));  //O(n)n次才好

        return 0;

    }

    意义:

    当算法在最坏情况下仍然能满足需求时,可以推断,算法的最好情况和平均情况都满足需求。

    在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度。

    1. 算法的空间复杂度

    算法的空间复杂度通过计算算法的存储空间实现

    S(n) = S(n) = ) =O(f(n))

    其中,n为问题规模,f(n)为在问题规模为n时所占用存储空间的函数。

    空间复杂度表示申请的空间大小,大O表示法同样适用于算法的空间复杂度。当算法执行时所需要的空间是常数时,空间复杂度为O(1),为n时是O(n)

     

    1. 空间与时间的策略

    (1) 多数情况下,算法执行时所用的时间更令人关注。

    (2) 如果有必要,可以通过增加空间复杂度来降低时间复杂度。

    (3) 同理,也可以通过增加时间复杂度来降低空间复杂度。

    l 在实现算法时需要分析具体问题对执行时间和空间的要求。

    例子:

    #include <stdio.h>

    /*

        问题:

        在一个由自然数1-1000中某些数字所组成的数组中,每个数字可能出现零次或者多次。

        设计一个算法,找出出现次数最多的数字。

    */

    void search(int a[], int len)

    {

        int sp[1000] = {0};

        int i = 0;

        int max = 0;

        for(i=0; i<len; i++)

        {

            int index = a[i] - 1;

            

            sp[index]++;

        }   

        for(i=0; i<1000; i++)

        {

            if( max < sp[i] )

            {

                max = sp[i];

            }

        }   

        for(i=0; i<1000; i++)

        {

            if( max == sp[i] )

            {

                printf("%d ", i+1);

            }

        }

    }

     

    int main()

    {

        int array[] = {1, 1, 3, 4, 5, 6, 6, 6, 2, 3};

        search(array, sizeof(array)/sizeof(*array));  

        return 0;

    }

    这个算法很好。

    思考:

    当两个算法的大O表示法相同的时候,是否意味着两个算 ,是否意味着两个算法的效率完全相同?

  • 相关阅读:
    Java 设计模式(2)工厂模式
    Java 设计模式-六大原则
    华为机试测试- 求有序数组中最长的等差序列
    JAVA SE 基础复习-面向对象(2) static
    Java 设计模式
    Java 字符串
    jQuery源代码学习之七—队列模块queue
    jQuery源代码学习之六——jQuery数据缓存Data
    jQuery源代码学习之五——jQuery.when
    javascript源代码学习之五——jQuery.deferred
  • 原文地址:https://www.cnblogs.com/free-1122/p/9884925.html
Copyright © 2020-2023  润新知