首页/数据结构/绪论/算法的空间复杂度分析 🔗 在 Obsidian 中打开
数据结构 · 绪论

算法的空间复杂度分析

难度 ★★★重要度 ★★★★ 考查频率 高题型 选择 / 算法分析 辅助空间原地算法递归栈
速查
空间复杂度衡量算法运行所需的额外存储空间随问题规模 $n$ 的增长趋势,记为 S(n) = O(f(n))只算辅助空间,不含输入数据本身。原地算法 $S(n)=O(1)$;递归算法的空间复杂度 = 递归栈最大深度

概述

空间复杂度衡量算法运行过程中额外占用的存储空间随问题规模 $n$ 的增长趋势。注意:只计算辅助空间,不包括输入数据本身占用的空间。

分析方法:① 分析声明的变量、数组、递归栈等额外空间;② 统计与 $n$ 的关系;③ 用大 O 写出 $S(n)$。

核心概念

原地算法(In-place):空间复杂度为 $O(1)$ 的算法,只需常数级额外空间。如冒泡排序、插入排序是原地算法;归并排序(需辅助数组)不是原地算法。

递归算法的空间复杂度需考虑递归调用栈的深度。递归深度为 $n$ 时,空间复杂度至少为 $O(n)$。

// 递归求阶乘:递归深度 = n,空间复杂度 O(n)
int fact(int n){
  if(n<=1) return 1;
  return n * fact(n-1);   // 每层调用占用栈帧
}

关键性质

空间复杂度含义典型算法
$O(1)$常数级辅助空间(原地)冒泡、选择、插入排序
$O(\log n)$对数级辅助空间快速排序(平均递归栈)
$O(n)$线性级辅助空间归并排序(辅助数组)、基数排序
$O(n^2)$平方级辅助空间某些动态规划

常见考法

命题套路求空间复杂度(数组大小 + 递归栈深度)、判断是否为原地算法、比较排序算法的辅助空间开销。
考法解题套路
求空间复杂度统计辅助空间:数组大小 + 递归栈深度
是否原地空间复杂度是否为 $O(1)$
递归算法递归栈深度 = 递归调用最大层数
比较排序冒泡/插入 $O(1)$,快排平均 $O(\log n)$,归并 $O(n)$

易错点

必记
  1. 空间复杂度不含输入数据:对 $n$ 个元素排序,输入的 $n$ 个元素空间不计入。
  2. 递归的隐含空间:递归调用栈容易被忽略,深度为 $d$ 时栈空间至少 $O(d)$。
  3. $O(1)$ 不代表没有额外空间:表示与 $n$ 无关、常数级。
  4. 时间/空间可独立分析:可做到 $O(n^2)$ 时间、$O(1)$ 空间。
  5. 递归深度 ≠ 递归次数:空间看栈深度,时间看调用总次数。

核心结论

  1. 空间复杂度只计算辅助空间,不含输入数据。
  2. 原地算法空间复杂度 $O(1)$,空间效率最高。
  3. 递归算法的空间复杂度 = 递归栈最大深度
  4. 常见排序:冒泡/选择/插入/希尔 $O(1)$;快排平均 $O(\log n)$、最坏 $O(n)$;归并 $O(n)$;基数 $O(n+r)$。

记忆卡片

空间复杂度含输入数据吗?
不含,只算辅助空间。
什么是原地算法?
空间复杂度 $O(1)$ 的算法。
递归空间看什么?
递归栈最大深度。
快排空间复杂度?
平均 $O(\log n)$,最坏 $O(n)$。
归并空间复杂度?
$O(n)$,需辅助数组。
$O(1)$ 含义?
额外空间与 $n$ 无关(常数级)。

交互动画 · 递归调用栈空间逐步演示

递归函数 f(n) = n + f(n−1),f(1)=1:观察栈帧逐层压入与弹栈,最大栈深即辅助空间 f(1) · 基准返回 f(2) = 2 + f(1) f(3) = 3 + f(2) f(4) = 4 + f(3) f(5) = 5 + f(4) 栈底 当前栈深:0 最大栈深 = 5 ⇒ 空间 O(n) 空间量级对比 O(1) log n O(n)
点击「播放」或「下一步」:观察 f(5) 一路递归压栈到 f(1),再逐层弹栈回代

相关知识点

time-complexity-analysis best-worst-avg-time-complexity

↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。