当前位置 : 主页 > 编程语言 > python >

[数据结构]复杂度分析

来源:互联网 收集:自由互联 发布时间:2022-06-18
一 为什么需要复杂度分析 测试结果非常的依赖测试环境 在不同的硬件环境,测试同样一份代码其效果是不一样的。那么复杂度分析具有成本低,效率高的特点。 测试结果收到数据规模


一 为什么需要复杂度分析

  • 测试结果非常的依赖测试环境
  • 在不同的硬件环境,测试同样一份代码其效果是不一样的。那么复杂度分析具有成本低,效率高的特点。

  • 测试结果收到数据规模的影响很大
  • 比如排序算法,对待排序的有序度不一样,排序的执行时间就很不一样。如果测试数据规模很小,测试结果也无法真实反应算法的性能。比如对于小规模的数据排序,插入排序可能比快排更快。

    二. 大0复杂度表示法

    算法的执行效率一般来说就是算法代码执行的时间。那么如何得到代码的执行时间?先列出代码
    假设每行代码执行时间一样。

    int calc(int n)
    {
    int sum=0;//执行一个time
    int i=1;//执行一个time
    int j=1;//执行一个time
    //循环了n遍 所以是2n*time
    //从此整个时间T(n) = (2n2+2n+3)*time
    for(;i<=n;++i)
    {
    j=1;
    for(;j<=n;j++)
    {
    sum=sum+i*j
    }
    }
    }

    从这里出现一个重要的规律就是所有代码的执行时间T(n)和每行代码的执行此时n成正比Tn=O(f(n))。上面出现T(n)=2n<sup>2</sup>+2n+3,我们只需要记录一个最大量级就行。比如T(n)=O(n<sup>2</sup>).

    三. 时间复杂度分析三方法

  • 只关注循环次数最多的一段代码
  •     大O表示法,是表示一种变化的趋势。我们只需要关心一个最大阶的量级。比如下面这个代码

    int calc(int n)
    {
    int sum=0;
    int i=0;
    for(;i<=n;++i)
    {
    sum=sum+i;
    }
    return sum;
    }

        这里直接查看for部分代码,这两行代码被执行了n次,所以总的时间复杂度为O(n)

  • 加法法则 总的复杂度等于量级最大的那段代码
  • int calc(int n)
    {
    int sum=0;//执行一个time
    int i=1;//执行一个time
    int j=1;//执行一个time

    int p = 0;
    for(int p=0;p<n;p++)
    {
    sum=sum+p;
    }
    sum=0;
    //循环了n遍 所以是2n*time
    //从此整个时间T(n) = (2n2+2n+3)*time
    for(;i<=n;++i)
    {
    j=1;
    for(;j<=n;j++)
    {
    sum=sum+i*j
    }
    }
    }

        这段代码中第一个循环p循环n次,不管这个n是100,1000等,都是产量级的时间。同理第二个第二段循环代码为O(n<sup>2</sup>),所以最终结果是O(n<sup>2</sup>)

  • 乘法法则 嵌套代码复杂度等于嵌套内外代码复杂度的乘积
  •     假设T1(n)=O(n),T2(n)=O(n),那么T(n)=T1(n)*T2(n)=O(n<sup>2</sup>)

    四 几种常见的时间复杂度分析

  • 常见复杂度有哪些
  • [数据结构]复杂度分析_执行时间

  • 0(1)
  • int i=2;
    int j=3;
    int sum=i+j;

    一般来说如果代码的执行时间不随着n的增大而增长,那么就是O(1)。小技巧就是程序中没有循环,递归等

  • O(logn)和O(nlogn)
  • int i=1;
    while(i<=n)
    {
    i=i*2;
    }

    这里的i从1开始每次循环乘以2直到i小于了n结束。也就是2<sup>0</sup>,2<sup>1</sup>.....2<sup>x</sup>,那么2<sup>x</sup>=n,x=log2n.这个时候如果i=i\*4,那就是x=log<sub>4</sub>n,那么log<sub>4</sub>n实际上等于log<sub>4</sub>2\*log<sub>2</sub>n,所以呢O(log<sub>4</sub>n)=O(C*log<sub>2</sub>n).之前说过我们的这个C常量,可以忽略。所以O(log4n)=O(log2n).在对数阶时间复杂度表示中,忽略对数的

    4 O(m+n)和O(m*n)

    int cal(int m, int n)
    {
    int sum_1 = 0;
    int i = 1;
    for (; i < m; ++i)
    {
    sum_1 = sum_1 + i;
    }
    int sum_2 = 0;
    int j = 1;
    for (; j < n; ++j)
    {
    sum_2 = sum_2 + j;
    }
    return sum_1 + sum_2; }
    }

    这里的m和n那个量级大不好预判

    五. 面试中常见算法的复杂度

  • 排序相关
  • [数据结构]复杂度分析_执行时间_02

  • 二叉树相关
  • [数据结构]复杂度分析_时间复杂度_03

    六 总结

  • 学习复杂度分析有利于我们编写更加优秀的代码。
  • 复杂度分析的要点
  • (1) 单段代码看高频。比如看循环
    (2) 多段代码取最大。比如既有单层循环也有多层循环,取高层
    (3) 嵌套代码求乘积。比如递归

  • 常用的复杂度
  • (1) 多项式阶
        O(1)常数阶 O(logn)对数阶 O(n)线性阶 o(n<sup>2</sup>)平方阶
    (2) 非多项式
        指数阶 阶乘阶

    上一篇:[Linux学习]平均负载是什么
    下一篇:没有了
    网友评论