in Algorithm

算法复杂度和大O表示法

概念

SICP算法复杂度是算法分析里的概念(对应到SICP里的增长阶),是衡量计算资源消耗数量(例如计算时间,存储器使用等)的指标。

算法的复杂度在理论上表示为一个函数:其定义域是输入数据的长度(通常考虑任意大的输入,没有上界),值域通常是执行步骤数量(时间复杂度)或者存储器位置数量(空间复杂度)。

这个函数形如:

R(n) = Θ(f(n)) 亦可记做 O(f(n))

f(n) 就是被度量的算法主体;算法的复杂度标记就是大O(Θ读做theta),这种记法称为大O表示法

常见复杂度级别

  • Θ(1) 常数级别
  • Θ(log(n)) 对数级别
  • Θ(n) 线性级别
  • Θ(n*log(n)) 线性对数级别
  • Θ(n^2) 平方级别
  • Θ(2^n) 指数级别

直观感受

基于规模n 各级别算法 与 复杂度 的关系:

Big-O_Complexity_Chart

各种排序算法的复杂度:

Complexity of Array Sorting Algorithms

例子

求幂算法 b^n(b的n次方),如果使用递归的形式来表达,有:
b^n = b * b^(n-1)
b^0 = 1

我们用 Racket 将它翻译为如下过程:

可以看出,对于任意的输入规模 n,它都是线性的递归计算(线性递归),时间和空间复杂皆为 Θ(n)

我们知道,有限递归算法都可以优化成线性迭代形式,于是就有了:

不难发现,这个算法的时间复杂度还是线性的,变换成迭代形式后,优化的是空间复杂度(Lisp是应用序求值,即调用函数时会先求值参数而后应用;结合递归算法,就有一个展开的空间开销),降至了 Θ(1)

还有优化的余地,因为,幂函数可以表示为:

b^n = (b^(n/2))^2 当n是偶数时
b^n = b * b^(n-1) 当n是奇数时

所以,算法可以通过迅速降幂,优化成对数级别

时间和空间上复杂度皆为 Θ(log(n))

所以,递归就一定比迭代算法慢吗?未必~

引用

  1. http://bigocheatsheet.com/
  2. https://mitpress.mit.edu/sicp/full-text/book/book.html
打赏作者
您的支持将激励我继续创作!

您的支持将鼓励我们继续创作!

[微信] 扫描二维码打赏

[支付宝] 扫描二维码打赏

Write a Comment

Comment