复杂度分析的套路及常见的复杂度

前言

本篇文章收录于专辑:http://dwz.win/HjK,点击解锁更多数据结构与算法的知识。算法

你好,我是彤哥,一个天天爬二十六层楼还不忘读源码的硬核男人。数组

上一节,咱们一块儿学习了表示复杂度的几个符号,咱们说,一般使用大O来表示算法的复杂度,不只合理,并且书写方便。数据结构

那么,使用大O表示法评估算法的复杂度有没有什么套路呢?以及常见的复杂度有哪些呢?架构

本节,咱们就来解决这两个问题。ide

前情回顾

在正式讲解套路以前,咱们先回忆一下前面几节讲到的内容。函数

在第2节,咱们学习了渐近分析法,将算法的复杂度与输入规模挂钩,随着输入规模的增大,算法执行的时间将呈现一种什么样的趋势,将这个趋势用函数表示,再去除低阶项和常数项,就获得了算法的时间复杂度。学习

在第3节,咱们分别从最坏、平均、最好三种状况来分析了算法的复杂度,得出结论,通常使用最坏状况来评估算法的复杂度。blog

在第4节,咱们经过动态数组的插入元素及经典快速排序的时间复杂度,解释了有的时候不能使用最坏状况来评估算法的复杂度。排序

在第5节,咱们从读音、数学、通俗理解三个方面分析了各类表示算法复杂度的符号,得出结论仍是使用大O比较香,大O表明了算法的上界,它与前面讲到的最坏状况每每是对应的。索引

因此,这里所说的套路也是针对大部分状况,也就是最坏状况,对于一些个例,好比经典快排,咱们虽然也是使用大O表示他们的复杂度,可是,实际上是一种均摊的复杂度。

好了,让咱们看看计算算法复杂度的套路究竟是什么吧。

套路

我将计算算法复杂度的套路概括为如下五步:

  1. 明确输入规模n;
  2. 考虑最坏状况或均摊状况,若是最坏状况为个例,那就是均摊;
  3. 计算算法执行的次数与n的关系,并用函数表示出来;
  4. 去除低阶项;
  5. 去除常数项;

好比,对于在数组中查找指定元素的操做:

  1. 输入规模为数组的长度n;
  2. 考虑最坏状况为目标元素不在数组中;
  3. 算法的执行次数为遍历全部数组元素,也就是n次,用函数表示f(n) = n;
  4. 去除低阶项,没有低阶项,仍是n;
  5. 去除常数项,没有常数项,仍是n;

因此,在数组中查找指定元素的时间复杂度为O(n)。

OK,使用这种方式能够很快的计算出算法的复杂度,也不须要进行额外的计算,很是快捷高效。

常见的复杂度

上面咱们说了,复杂度的计算就是计算与输入规模n的关系,因此,咱们想一想数学中关于n的函数就能得出常见的复杂度了,我绘制了一张表格:

与n的关系 英文释义 复杂度 示例
常数(不相关) Constant O(1) 数组按索引查找元素
对数相关 Logarithmic O(logn) 二分查找
线性相关 Linear O(n) 遍历数组的元素
超线性相关 Superlinear O(nlogn) 归并排序、堆排序
多项式相关 Polynomial O(n^c) 冒泡排序、插入排序、选择排序
指数相关 Exponential O(c^n) 汉诺塔
阶乘相关 Factorial O(n!) 行列式展开
n的n次方 O(n^n) 不知道有没有这种算法

在这张表中,复杂度是依次增长的,能够看到常数复杂度O(1)无疑是最好的,让咱们用一张图来直观感觉下:

复杂度分析的套路及常见的复杂度

后记

本节,咱们一块儿学习了复杂度分析的套路以及常见的复杂度,到目前为止,咱们无论是举例仍是讲解基本上都在说时间复杂度。

那么,空间复杂度又是什么呢?空间与时间之间如何权衡呢?

下一节,咱们接着聊。

关注公号主“彤哥读源码”,解锁更多源码、基础、架构知识。

相关文章
相关标签/搜索