算法分析

2094 字
10 分钟
算法分析
Warning

含AI生成内容

算法分析#

算法的基本概念#

算法(Algorithm)是对特定问题求解步骤的描述,是一个有穷的指令序列。算法与程序不同——程序可以无穷运行(如操作系统主循环),但算法必须有穷。

算法的五大特性#

特性含义说明
有穷性必须在有限步后结束,每一步在有限时间内完成算法必须有终止条件;程序未必有穷
确定性每条指令含义明确,相同输入只能产生相同输出不能有二义性
可行性所有操作都可通过已实现的基本运算有限次执行完成理论上的操作必须能实际执行
输入有零个或多个输入取自特定数据对象的集合
输出至少有一个输出结果是算法存在的意义

易错:有穷性强调”会停下来”,确定性强调”没有歧义”,两者是不同的概念。408 选择题经常将这两个特性放在一起让考生辨析。

好算法的四个目标#

目标含义
正确性算法能正确解决问题,满足需求规格
可读性便于理解、调试和维护(不追求极致技巧而牺牲可读性)
健壮性能处理非法输入,不会异常崩溃
高效率与低存储时间复杂度和空间复杂度尽可能低

时间复杂度#

时间复杂度是对算法运行时间随问题规模增长而增长的趋势的度量。实际使用事前分析法——统计算法中基本操作的执行次数 T(n) 作为时间度量,而非具体的运行时间(运行时间受硬件、编程语言等外部因素影响)。

渐近记号#

记号名称数学含义直观理解
O (Big O)渐近上界T(n) ≤ C·f(n) 当 n ≥ n₀算法不会比 f(n) 更差
Ω (Omega)渐近下界T(n) ≥ C·g(n) 当 n ≥ n₀算法不会比 g(n) 更好
Θ (Theta)渐近紧界C₁·h(n) ≤ T(n) ≤ C₂·h(n) 当 n ≥ n₀算法以 h(n) 为增长量级
  • 大 O 记号是 408 考研中使用最频繁的记号。默认情况下,题目问”时间复杂度”通常指最坏时间复杂度,并用大 O 表示。
  • 大 O 记号忽略低阶项和常数系数,只保留最高阶项。

计算规则

  1. 加法规则:T(n) = T₁(n) + T₂(n) = O(f(n)) + O(g(n)) = O(max(f(n), g(n)))
  2. 乘法规则:T(n) = T₁(n) × T₂(n) = O(f(n)) × O(g(n)) = O(f(n) × g(n))

常见时间复杂度排序#

O(1) < O(log n) < O(n) < O(n log n) < O(n²) < O(n³) < O(2ⁿ) < O(n!)
复杂度名称典型算法说明
O(1)常数阶哈希查找、数组按下标访问执行时间与 n 无关
O(log n)对数阶折半查找、BST 查找(平均)每次迭代将问题规模减半
O(n)线性阶顺序查找、遍历执行时间与 n 成正比
O(n log n)线性对数阶快速排序、归并排序、堆排序分治策略的典型复杂度
O(n²)平方阶冒泡排序、直接插入排序、简单选择排序双重循环
O(n³)立方阶矩阵乘法的朴素算法三重循环
O(2ⁿ)指数阶穷举子集n 稍大即不可行
O(n!)阶乘阶穷举全排列增长速度极快

典型分析模式#

// 模式 1:单层循环 → O(n)
for (int i = 0; i < n; i++)
x++;
// 模式 2:双层嵌套循环 → O(n²)
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
x++;
// 模式 3:对数循环 → O(log n)
int i = 1;
while (i <= n)
i = i * 2; // 执行次数 = ⌈log₂n⌉
// 模式 4:循环变量倍增 → O(√n)
int i = 0;
while (i * i <= n)
i++;
// 模式 5:嵌套但内层与外层相关 → O(n²)
for (int i = 0; i < n; i++)
for (int j = 0; j < i; j++) // 总次数 = 0+1+2+...+(n-1) = n(n-1)/2
x++;

易错:判断循环复杂度时,不要只看有几层循环,还要看循环变量的变化方式。对数是 O(log n) 而不是 O(n),倍增/减半(i*=2 / i/=2)是对数增长的典型特征。

最好、最坏与平均时间复杂度#

情况含义考研中的用法
最好时间复杂度输入最有利时的运行时间参考价值有限
最坏时间复杂度输入最不利时的运行时间考试默认就是最坏情况
平均时间复杂度所有可能输入的加权平均需要明确说明时才计算

递归算法的时间复杂度#

递归算法的时间复杂度分析通常通过递推公式进行。常见形式:

  • T(n) = T(n-1) + O(1) → O(n)(如递归遍历链表)
  • T(n) = 2T(n/2) + O(n) → O(n log n)(如归并排序)
  • T(n) = T(n/2) + O(1) → O(log n)(如折半查找的递归版)
  • T(n) = 2T(n-1) + O(1) → O(2ⁿ)(如斐波那契数列的朴素递归)

主定理(Master Theorem):对于形如 T(n) = aT(n/b) + f(n) 的递推式,主定理提供了快速求解渐近紧界的框架。408 考研中可以直接用递推展开法求解,主定理可作为补充。


空间复杂度#

空间复杂度 S(n) 度量的是算法除输入数据外额外需要的辅助空间大小。

常见空间复杂度#

空间复杂度含义示例
O(1)原地工作,只用常数个额外变量冒泡排序、直接插入排序、链表逆置
O(n)需要与输入规模同量级的辅助空间归并排序的辅助数组、顺序表动态扩容
O(log n)递归深度为 log n快速排序的递归栈(平均情况)
O(n)递归深度为 n快速排序的递归栈(最坏情况)

注意:递归算法的空间复杂度 = 递归调用的深度(每层递归在栈上占用常数空间时)。

传值与传指针的空间开销#

  • 传值(Pass by Value):将实参的完整副本传递给函数。如果实参是大型结构体(如包含大量元素的数组),传值会造成 O(n) 的额外空间开销。
  • 传指针/引用(Pass by Pointer/Reference):只传递地址(4 或 8 字节),无论实参多大,空间开销始终为 O(1)。408 伪代码中的 & 符号(C++ 引用)即表示传引用。

易错:分析空间复杂度时,函数的形参也需要考虑。传入的数组指针本身(4 或 8 字节)不算额外空间,但如果函数通过传值方式接收整个数组,则需要将数组大小计入空间复杂度。


复杂度分析实例#

复杂度分析方法在实际数据结构中的应用:

  • 顺序表(Sequential List):按位查找 O(1)、按值查找 O(n)、插入删除 O(n)(平均移动 n/2 个元素)——这些复杂度分析直接决定顺序表的适用场景
  • 链表(Linked List):按位查找 O(n)(顺序访问)、已知前驱时插入 O(1)——链表的 O(n) 查找成本是其核心局限

考研高频考点#

  • ⭐ 给定代码段,分析时间复杂度(选择题/应用题几乎每年必考)
  • ⭐ 常见复杂度的大小排序(选择题)
  • ⭐ 递归算法的时间/空间复杂度分析(难度较高,应用题偶考)
  • ⭐ 算法的五个特性(选择题)
  • 大 O 记号的数学定义
  • 最好/最坏/平均时间复杂度的区别
  • 空间复杂度的含义(不包含输入数据占用的空间)
  • 传值与传指针在空间开销上的区别

易错:时间复杂度分析的是基本操作的执行次数,不是具体运行时间。O(n) 的算法不一定比 O(n²) 的算法快——大 O 描述的是增长趋势,只在 n 足够大时才有意义。

易错:算法不一定要写成程序——可以用自然语言、流程图、伪代码等描述。有穷性是算法与程序的本质区别。


关联页面#

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

算法分析
https://lingluoa.icu/posts/algorithm-analysis/
作者
lingluoa
发布于
2026-07-04
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
lingluoa
Hello, I'm lingluoa.
公告
欢迎来到我的博客!不定期更新中。
文章目录
标签
站点统计
文章
53
分类
9
标签
75
总字数
175,771
运行时长
0
最后活动
0 天前
站点信息
构建平台
ESA Pages
博客版本
Firefly v6.15.6
文章许可
CC BY-NC-SA 4.0