• 数据结构与算法学习笔记(二)


    1. 算法效率的度量方法:
      1. 事后统计法:通过设计好的测试程序和数据,利用计算机计时器对不同算法编制的程序的运行时间进行比较,从而确定算法效率的高低。缺陷:必须依据算法事先编制好测试程序,通常需要花费大量时间和精力。不同测试环境差别也很大。
      2. 事前分析估算法:在计算机程序编写签,依据统计方法对算法进行估算。
    2. 高级语言编写的程序在计算机上运行时所耗的时间取决于下列因素:
      1. 算法采用的策略,方案
      2. 编译产生的代码质量
      3. 问题的输入规模
      4. 机器执行指令的速度
    3. 研究算法的复杂度,侧重的是研究算法随着输入规模扩大增长量的一个抽象,而不是精确地定位需要执行多少次。在分析一个算法的运行时间时,重要的是把基本操作的数量和输入模式关联起来。
    4. 函数渐进增长:给定两个函数f(n)和g(n),如果存在一个整数N,使得对于所有的n>N,f(n)总是比g(n)大,那么,我们说f(n)的增长渐近快于g(n)。
    5. 判断一个算法的效率时,函数中的常数和其他次要项常常可以忽略,而更应该关注主项(最高项)的阶数。
    6. 算法的时间复杂度:在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级。算法的时间复杂度,也就是算法的时间量度,记做:T(n)=O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称为时间复杂度。其中f(n)是问题规模n的某个函数。(这里的时间指的是执行的次数)
    7.  用大写O()来体现算法时间复杂度的记法,我们称之为大O记法。
    8. 一般情况下,随着输入规模n的增大,T(n)增长最慢的算法为最优算法。
    9. 如何分析一个算法的时间复杂度:
      1. 用常数1取代运行时间中的所有加法常数
      2. 在修改后的运行次数函数中,只保留最高阶项
      3. 如果最高阶项存在且不是1,则去除与这个项相乘的常数
      4. 得到最后的结果就是大O阶
      5. int sum = 0, n = 100;
        printf("aaaaaaaaaaaa
        ");
        printf("aaaaaaaaaaaa
        ");
        printf("aaaaaaaaaaaa
        ");
        printf("aaaaaaaaaaaa
        ");
        printf("aaaaaaaaaaaa
        ");
        printf("aaaaaaaaaaaa
        ");
        sum = (1+n)*n/2
        //这段代码的时间复杂度为O(1),因为这段代码执行了8次,没有与n相关,常数都简化为1
    10. 线性阶:一般含有非嵌套循环设计线性阶,线性阶就是随着问题规模n的扩大,对应计算次数呈直线增长。
      1. int i, n = 100, sum = 0;
        for(i = 0; i<n; i++) {
            sum = sum + i;
        }

         上面这段代码的循环复杂度为O(n),因为循环体中的代码需要执行n次

    11. 平方阶
      1. int i,j,n = 100;
        for(i = 0; i < n; i++) {
            for(j = 0; j < n; j++) {
                printf("aaaaaaaaaaaa
        ");
            }
        }

        上面这段代码的时间复杂度为O(n²)。

      2. int i,j,n = 100;
        for(i = 0; i < n; i++) {
            for(j = i; j < n; j++) {
                pringtf("aaaaaaaaaaaaaa
        ");
            }
        }  

         分析,由于当i=0时,内循环执行了n次,当i=1时,内循环则执行n-1次。。。。。。当i=n-1时,内循环执行1次,所以总的执行次数应该是n+(n-1)+(n-2)+...+1=n(n+1)/2用上面的简化方法来简化½n²+½n,这个式子中没有常数项不用考虑第一条,根据第二条只保留最高项,去掉½n这一项,根据第三条去掉与最高项相乘的常数½,最终得到O(n²)

    12. 对数阶
      1. int i = 1, n = 100;
        while(i < n) {
            i = i*2;
        }

         由于每次i*2之后就距离n更近一步,假设有x个2相乘后大于或等于n,则会退出循环。于是由2x=n得到x=log2n,所以这个循环的时间复杂度为O(logn)。

      1. int i,j;
        for(i = 0; i < b; i++) {
            function(i);
        }
        
        void function(int count) {
            printf("%d",count);
        }

         function函数的时间复杂度是O(1),所以整体的时间复杂度就是循环的次数O(n)。

      1. int i,j;
        for(i = 0; i < b; i++) {
            function(i);
        }
        
        void function(int count) {
            int j;
            for (j = count; j < n;j++) {
                printf("%d",j);
            }
        }

         和平方阶中第二个例子一样,function内部的循环次数随count的增加而减少,所以根据方法简化后的时间复杂度为O(n²)

      1. n++;-------------------------------------执行1次
        function(n);-----------------------------执行n²次
        for(i = 0;i < n; i++) {------------------执行n²次
            function(i);
        }
        for(i = 0;i < n; i++) {------------------执行n²次
            for(j = i;j < n; j++) {
                printf("%d",j);
            }
        }
        void function(int count) {
            int j;
            for (j = count; j < n;j++) {
                printf("%d",j);
            }
        }

         上面几次操作是并列的,整体的执行次数应该是各个操作执行次数之和3n²+1,简化后得到时间复杂度为O(n²)

    13. 常见的时间复杂度
    例子 时间复杂度 术语
    5201314 O(1) 常数阶
    3n+4 O(n) 线性阶
    3n²+4n+5 O(n²) 平方阶
    3log2n+4 O(logn) 对数阶
    2n+3nlog2n+14 O(nlogn) nlogn阶
    n3+2n2+4n+6 O(n3) 立方阶
    2n O(2n) 指数阶

      17. 常见的时间复杂度所耗费的时间从小到大依次是

            O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < (nn)

      18. 平均运行时间是期望的运行时间

        19. 最坏运行时间是一种保证。在应用中,这是一种最重要的需求,通常除非特别指定,我们提到的运行时间都是最坏情况的运行时间。

      20. 算法的空间复杂度通过计算算法所需的存储空间实现,算法的空间复杂度的计算公式记做S(n) = O(f(n)),其中,n为问题的规模,f(n)为语句关于n所占存储空间的函数。

      21. 通常,我们都是用“时间复杂度”来指运行时间的需求,用“空间复杂度”指空间需求。

      22. 当直接让我们求“复杂度”时,通常指的是时间复杂度。

  • 相关阅读:
    Proteus仿真与实际的差别
    用 Proteus学习51单片机之1602液晶
    用Proteus学习51单片机之中断
    用Proteus学习51单片机之键盘
    用Proteus学习51单片机之数码管
    PHPnow 安装服务 [ Apache_pn ] 失败的解决方法 for[windows7/vista]
    chrome 不能打印背景图的解决方法
    JS 无块级作用域
    IE6下zindex犯癫不起作用bug的初步研究
    ie6下的js调试工具companion.js
  • 原文地址:https://www.cnblogs.com/czq1989/p/5219624.html
Copyright © 2020-2023  润新知