复杂度分析
复杂度分析
一、为什么需要复杂度分析
正常我们跑一边代码,通过监控就可以得到算法执行时间和内存大小,这种方法也叫事后统计法,但是这样得方法有着很大得局限性
1.测试结果非常依赖测试环境
不同得测试环境对测试结果有这不一样得结果,同样得代码在不同硬件得服务器上执行效率也是不一样得,比如i9一定比i5处理器得执行速度要快
2.测试结果受数据规模得影响很大
对同一个排序算法,待排序数据的有序度不一样,排序的执行时间就会有很大的差别。极端情况下,如果数据已经是有序的,那排序算法不需要做任何操作,执行时间就会非常短。除此之外,如果测试数据规模太小,测试结果可能无法真实地反映算法的性能。比如,对于小规模的数据排序,插入排序可能反倒会比快速排序要快!
所以总结下来就是和性能测试相比,复杂度分析有不依赖执行环境、成本低、效率高、易操作、指导性强的特点,掌握复杂度分析,将能编写出性能更优得代码。
二、如何进行复杂度分析
大O表示法
算法的执行效率,粗略地讲,就是算法代码执行的时间,所有代码的执行时间T(n)与每行代码的执行次数f(n)成正比,我们可以把这个规律总结成一个公式
T(n) = O(f(n))
示例
int cal(int n) {
int sum = 0;
int i = 1;
for (; i <= n; ++i) {
sum = sum + i;
}
return sum;
}
根据示例代码,T(n) 我们已经讲过了,它表示代码执行的时间;n 表示数据规模的大小;f(n) 表示每行代码执行的次数总和,O,表示代码的执行时间 T(n) 与 f(n) 表达式成正比
在上述示例中,T(n) = O(2n+2),这就是大 O 时间复杂度表示法。大 O 时间复杂度实际上并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,也叫作渐进时间复杂度,简称时间复杂度。
当n很大时,公式中的低阶、常量、系数三部分并不左右增长趋势,所以可以忽略
1.时间复杂度分析
1.1 分析方法
- 单段代码看次数,只关注循环执行次数最多的一段代码
int cal(int n) {
int sum = 0;
int i = 1;
for (; i <= n; ++i) {
sum = sum + i;
}
return sum;
}
上述代码,第2、3行是常量级执行时间,与n大小无关 ,所以对复杂度没有影响,循环执行次数最多的是第4、5行,这两行代码执行了n次,所以时间复杂度是O(n)
- 多段代码取复杂度最高的,比如一段代码中有单循环和多重循环,那么取多重循环的复杂度
- 嵌套代码求乘积:比如递归、多重循环等,嵌套代码的复杂度等于嵌套内外代码复杂度的乘积
1.2 常见的几种时间复杂度
分为多项式量级和非多项式量级
1.2.1 多项式量级
- O(1)常量级O(1) 是常量级时间复杂度的一种表示方法,并不是指执行了一行代码,只要代码的执行时间不随 n 的增大而增长,这样代码的时间复杂度我们都记作 O(1)。或者说,只要算法中不存在循环语句、递归语句,即使有成千上万行的代码,其时间复杂度也是Ο(1)。
- O(logn)对数阶、O(nlogn)线性对数阶
- O(n)线性阶
- O(n²)平方阶
1.2.2 非多项式量级
- O(2ⁿ)指数阶
- O(n!)阶乘阶
2. 空间复杂度
间复杂度全称就是渐进空间复杂度,表示算法的存储空间与数据规模之间的增长关系
2.1 分析方法
- 主要考虑变量、数据结构、函数调用栈等占用的空间
2.2 常见空间复杂度
- O(1) - 常数空间:算法使用的额外空间不随输入规模变化
def constant_space(n):
total = 0
for i in range(n):
total += i
return total
- 无论n多大,只使用了固定数量的变量(`total`和`i`)
- 空间使用不随输入规模n变化
- 空间复杂度:O(1)
- O(n) - 线性空间:算法使用的额外空间与输入规模成线性关系
def linear_space(n):
result = []
for i in range(n):
result.append(i)
return result
- 创建了一个列表`result`,其大小与输入n成正比
- 当n增大时,所需空间线性增长
- 空间复杂度:O(n)
- O(n²) - 平方空间:算法使用的额外空间与输入规模的平方成正比
def quadratic_space(n):
matrix = []
for i in range(n):
row = []
for j in range(n):
row.append(i * j)
matrix.append(row)
return matrix
- 创建了一个n×n的二维列表
- 所需空间与n的平方成正比
- 空间复杂度:O(n²)

浙公网安备 33010602011771号