复杂度分析

复杂度分析

一、为什么需要复杂度分析

正常我们跑一边代码,通过监控就可以得到算法执行时间和内存大小,这种方法也叫事后统计法,但是这样得方法有着很大得局限性

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²)
posted @ 2025-05-22 17:12  Formerly0^0  阅读(28)  评论(0)    收藏  举报