数据结构与算法之美 03 | 复杂度分析(上)

复杂度分析(上):如何分析、统计算法的执行效率和资源消耗?

复杂度分析是整个算法的精髓,只要掌握了它,数据结构和算法的内容基本上就掌握了一半。

为什么需要复杂度分析?
1、程序测试结果非常依赖测试环境
2、测试结果受数据规模的影响很大

我们需要一个不用具体的测试数据来测试,就可以粗略的估计算法的执行效率的方法,
就是时间、空间复杂度分析方法。


大O复杂度表示法

Go语言示例代码:
func cal(n int) (sum int) {
sum = 0
for i:=0; i<=n; i++ {
sum = sum + i
}
return sum
}
假设每行代码执行的时间都一样,为 unit_time
第 2 行代码需要 1 个 unit_time 的执时间,第3、4行都运行了n遍,所以需要2*unit_time执行时间,
所以这段代码总的执行时间为(2n+1)*unit_time,可以看出所有代码的执行时间(Tn)与每行代码的执行次数成正比。

T(n) = O(f(n))
T(n): 代码执行的时间,n表示数据规模的大小
f(n): 每行代码执行的次数总和
O:表示代码的执行时间T(n)与f(n)表达示成正比

因此上面的示例T(n) = O(2n+1), 这就是大O时间复杂度表示法,
大O时间复杂度并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,
所以叫"渐进时间复杂度",简称"时间复杂度"

通常,公式中的 底数、常量、系数三部分并不左右增长趋势,所以都可以忽略。
用大O表示法表示上面代码的时间复杂度: T(n) = O(n)

Go语言示例代码:
func cal(n int) (sum int) {
sum = 0
for i:=0; i<=n; i++ {
for j:=0; j<=i; j++ {
sum = sum + i * j
}
}
return sum
}
用大O表示法表示上面代码的时间复杂度: T(n) = O(n*n)

时间复杂度分析的3个方法:
1、至关注循环执行次数最多的一段代码
2、总复杂度等于量级最大的那段代码的复杂度
3、嵌套代码的复杂度等于嵌套内外代码复杂度的乘积

几种常见时间复杂度实例:

多项式量级
1、常量阶 O(1)
2、对数阶 O(log*n) .... a的x次方=n,那么x叫做以a为底n的对数(logarithm),记作 x=loga*n
实例代码:
for i:=0 ; i<=n; {
i = i * 3
}
3、线性阶 O(n)
4、线性对数阶 O(n*log*n)
5、平方阶 O(n*n), 立方阶, K次方阶

非多项式量级
1、指数阶 O(2的n次方)
2、阶乘阶 O(n!)

当数据规模n越来越大时,非多项式量级算法的执行时间会急剧增加,
求解问题的执行时间会无线增长,所以非多项式时间复杂度算法效率非常低。
posted @ 2018-10-04 10:25  Vincen_shen  阅读(252)  评论(0编辑  收藏  举报