注
此专栏内容主要参考极客时间-数据结构与算法之美
事后统计法
- 一般测试进行的性能分析,都是属于“事后统计法”
- “事后统计法”不好的方面
- 测试结果依赖测试环境(比如测试机器配置)
- 测试结果受数据规模影响
大O表示法
- T(n) = O(f(n))
- T(n)表示执行时间,n表示数据规模大小,f(n)代表代码要执行的总次数
- 代码执行时间(空间)随数据规模增长的变化趋势,称为时间(空间)复杂度;
- 当n很大时,我们只要记录一个最大量级就可以了
时间复杂度分析
- 只关注循环次数最多的那一段代码
- 加法法则:总复杂度等于量级最大的那段代码的复杂度
- 乘法法则:嵌套代码复杂度等于嵌套内外代码复杂度的乘积
复杂度量级
- 多项式量级
- 非多项式量级:O(2n)、O(n!)
- 非多项量级算法是非常低效的算法
常见的时间复杂度
O(1)
只要代码中不存在循环、递归,不管多少行的代码,复杂度也是O(1)
O(logn)、O(nlogn)
示例代码
i=1;
while (i <= n) {
i = i * 2;
}
·
i=1;
while (i <= n) {
i = i * 3;
}
复杂度分析
O(log2n) = O(log23)*O(log3n)=O(log3n),使用大 O 标记复杂度的时候,可以忽略常数系数,即 O(Cf(n)) = O(f(n)),C忽略了。
所以,O(log2n)=O(log3n)=O(log10n)=O(logn)
同样的代码再循环执行n遍,那么复杂度就是O(nlogn)
O(m+n)、O(m*n)
- 需要将加法规则改为:T1(m) + T2(n) = O(f(m) + g(n))。但是乘法法则继续有效:T1(m)*T2(n) = O(f(m) * f(n))
常见的空间复杂度
O(1)、O(n)、O(n2)
常见的复杂度
从低阶到高阶有:O(1)、O(logn)、O(n)、O(nlogn)、O(n2 )
复杂度分析几个方面
最好、最坏情况时间复杂度
最好情况时间复杂度:在最理想的情况下,执行这段代码的时间复杂度;
最坏情况时间复杂度:在最糟糕的情况下,执行这段代码的时间复杂度;
平均时间复杂度:加权平均时间复杂度、期望时间复杂度;
摊平时间复杂度:使用率不多