目录

  • 一、什么是复杂度分析?
  • 二、为什么要进行复杂度分析?
  • 三、如何进行复杂度分析?
  • 1. 大O表示法
  • 2. 复杂度分析法则
  • 四、常用的复杂度级别?
  • 五、如何掌握好复杂度分析方法?
  • 1. 大O标记
  • 2. 最好情况时间复杂度、最坏情况时间复杂度和平均情况时间复杂度
  • 3. 均摊时间复杂度


一、什么是复杂度分析?

  1. 数据结构和算法解决的是:如何让计算机更快时间、更省空间的解决问题。
  2. 因此需从执行时间和占用空间两个维度来评估数据结构和算法的性能。
  3. 分别用时间复杂度和空间复杂度两个概念来描述程序性能,二者统称为复杂度。
  4. 复杂度描述的是算法执行时间(或占用空间)与数据规模的增长关系。

二、为什么要进行复杂度分析?

  1. 和性能测试相比,复杂度分析有不依赖执行环境、成本低、效率高、易操作、指导性强的特点。
  2. 掌握复杂度分析,将能编写出性能更优的代码,有利于降低系统开发和维护成本。

三、如何进行复杂度分析?

1. 大O表示法

1)来源

算法的执行时间与每行代码的执行次数成正比,用T(n) = O(f(n))表示,其中T(n)表示算法执行总时间,f(n)表示每行代码执行总次数,而n往往表示数据规模。

2)特点

以时间复杂度为例,由于时间复杂度描述的是算法执行时间与数据规模的增长变化趋势,所以常量阶、低阶以及系数实际上对这种增长趋势不产决定性影响,所以在做时间复杂度分析时忽略这些项。

2. 复杂度分析法则

1)单段代码看高频:比如循环。

2)多段代码取最大:比如一段代码中有单循环和多重循环,那么取多重循环的复杂度。

3)嵌套代码求乘积:比如递归、多重循环等。

4)多个规模求加法:比如方法有两个参数控制两个循环的次数,那么这时就取二者复杂度相加。

四、常用的复杂度级别?

多项式阶:随着数据规模的增长,算法的执行时间和空间占用,按照多项式的比例增长。

包括, O(1)(常数阶)、O(logn)(对数阶)、O(n)(线性阶)、O(nlogn)(线性对数阶)、O(行编辑器java 行编辑器的复杂度分析_行编辑器java)(平方阶)、O(行编辑器java 行编辑器的复杂度分析_行编辑器java_02)(立方阶)

非多项式阶:随着数据规模的增长,算法的执行时间和空间占用暴增,这类算法性能极差。包括, O(行编辑器java 行编辑器的复杂度分析_行编辑器java_03)(指数阶)、O(n!)(阶乘阶)

复杂度量级排序:

O(1) < O(logn) < O(n) < O(nlogn) < O(行编辑器java 行编辑器的复杂度分析_行编辑器java) < O(行编辑器java 行编辑器的复杂度分析_行编辑器java_02) < … < O(行编辑器java 行编辑器的复杂度分析_数据结构_06) < O(行编辑器java 行编辑器的复杂度分析_行编辑器java_03) < O(n!)

五、如何掌握好复杂度分析方法?

复杂度分析关键在于多练,所谓孰能生巧。

1. 大O标记

从 CPU 的角度来看,这段代码的每一行都执行着类似的操作:读数据-运算-写数据。尽管每行代码对应的 CPU 执行的个数、执行的时间都不一样,但是,我们这里只是粗略估计,所以可以假设每行代码执行的时间都一样,为 单位时间(unit_time)。

算法运行工作量(基本操作重复执行的次数总和)的大小是数据规模 n 的函数,记作:行编辑器java 行编辑器的复杂度分析_复杂度分析_08

则代码执行时间可表示为:
行编辑器java 行编辑器的复杂度分析_算法_09
大 O 时间复杂度实际上并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,行编辑器java 行编辑器的复杂度分析_复杂度分析_10 表示算法执行时间的增长率和 行编辑器java 行编辑器的复杂度分析_复杂度分析_08

时间复杂度的基本原则:

  1. 只有常数项,认为其时间复杂度为O(1)
  2. 顺序结构,时间复杂度按加法进行计算
  3. 循环结构,时间复杂度按乘法进行计算
  4. 分支结构,时间复杂度取最大值
  5. 判断一个算法的时间复杂度时,只需要关注最高次项,忽略最高次项的系数,且其它次要项和常数项也可以忽略
  6. 一般所分析的算法的时间复杂度都是指最坏时间复杂度

渐进式时间,空间复杂度分析只是一个理论模型,只能提供粗略的估计分析,我们不能直接就觉得O(logN)的算法一定优于O(n), 针对不同的宿主环境,不同的数据集,不同的数据量大小,在实际应用上面可能真正的性能会不同。

2. 最好情况时间复杂度、最坏情况时间复杂度和平均情况时间复杂度

当同一块代码在不同的情况下,时间复杂度有量级的差距时,使用这三种复杂度表示法来区分。

3. 均摊时间复杂度

对一个数据结构进行一组连续操作中,大部分情况下时间复杂度都很低,只有个别情况下时间复杂度比较高,而且这些操作之间存在前后连贯的时序关系,这个时候,我们就可以将这一组操作放在一块儿分析,看是否能将较高时间复杂度那次操作的耗时,平摊到其他那些时间复杂度比较低的操作上。而且,在能够应用均摊时间复杂度分析的场合,一般均摊时间复杂度就等于最好情况时间复杂度。