乐趣区

关于java:复杂度分析的套路及常见的复杂度

前言

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

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

上一节,咱们一起学习了示意复杂度的几个符号,咱们说,通常应用大 O 来示意算法的复杂度,不仅正当,而且书写不便。

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

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

前情回顾

在正式解说套路之前,咱们先回顾一下后面几节讲到的内容。

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

在第 3 节,咱们别离从最坏、均匀、最好三种状况来剖析了算法的复杂度,得出结论,个别应用最坏状况来评估算法的复杂度。

在第 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) 无疑是最好的,让咱们用一张图来直观感触下:

后记

本节,咱们一起学习了复杂度剖析的套路以及常见的复杂度,到目前为止,咱们不论是举例还是解说基本上都在说工夫复杂度。

那么,空间复杂度又是什么呢?空间与工夫之间如何衡量呢?

下一节,咱们接着聊。

关注公号主“彤哥读源码”,解锁更多源码、根底、架构常识。

退出移动版