跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

算法空间复杂度详解:概念与计算实例

算法空间复杂度衡量运行所需的额外临时存储空间,通常使用大 O 渐进表示法。它关注变量个数而非具体字节数,栈空间在编译期确定,主要看显式申请的额外空间。常见场景包括动态开辟二维数组(O(n^2))、原地排序(O(1))、动态数组存储(O(N))及递归调用(O(N))。掌握这些计算规则有助于评估程序内存效率。

魔法巫师发布于 2026/2/21更新于 2026/10/2595 浏览
算法空间复杂度详解:概念与计算实例

空间复杂度示意图

算法在编写成可执行程序后,运行时需要耗费时间资源和空间(内存)资源。因此衡量一个算法的好坏,一般是从时间和空间两个维度来衡量的,即时间复杂度和空间复杂度。

时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间。在计算机发展的早期,存储容量很小,所以对空间复杂度很是在乎。随着硬件发展,如今我们虽然不需要像过去那样特别关注空间复杂度,但在设计高效算法时,它依然是评估性能的重要指标。

大 O 的渐进表示法回顾

大 O 符号(big O notation):是用于描述函数渐进行为的数学符号。

推导大 O 阶的方法如下:

  1. 用常数 1 取代运行时间中的所有加法常数;
  2. 在修改后的运行次数函数中,只保留最高阶项;
  3. 如果最高阶项存在且其系数不是 1,则去除与这个项相乘的系数。得到的结果就是大 O 阶。

一、算法的空间复杂度

算法空间复杂度的定义:

  • 空间复杂度也是一个数学表达式,是对一个算法在运行过程中额外临时占用存储空间大小的量度。
  • 空间复杂度不是程序占用了多少 bytes 的空间,因为这个也没太大意义,所以 空间复杂度算的是变量的个数。
  • 空间复杂度计算规则基本跟时间复杂度类似,也使用大 O 渐进表示法。

注意: 函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,因此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定。


二、常见空间复杂度计算举例

1. 动态开辟二维数组

int** fun(int n) {
    int** s = (int**)malloc(n * sizeof(int*));
    for (size_t i = 0; i < n; ++i) {
        s[i] = (int*)malloc((i + 1) * sizeof(int));
    }
    return s;
}

解析: 这里开辟的是一个二维数组,数组有 n 行,每行分别有 1, 2, 3, …, n 列。总元素个数为 ,即 。根据大 O 推导法则,忽略低阶项和系数,空间复杂度为 。

1 + 2 + ... + n
n(n + 1)/2
O(n^2)

2. 冒泡排序

// 计算 BubbleSort 的空间复杂度?
void BubbleSort(int* a, int n) {
    assert(a);
    for (size_t end = n; end > 0; --end) {
        int exchange = 0;
        for (size_t i = 1; i < end; ++i) {
            if (a[i - 1] > a[i]) {
                Swap(&a[i - 1], &a[i]);
                exchange = 1;
            }
        }
        if (exchange == 0) break;
    }
}

解析: 此算法使用了常数个额外空间,分别是 end、exchange、i 等几个变量。无论输入规模 n 多大,额外申请的空间都是固定的。根据大 O 阶推导方法,空间复杂度为 O(1)。

3. 斐波那契数列(非递归)

// 计算 Fibonacci 的空间复杂度?
// 返回斐波那契数列的前 n 项
long long* Fibonacci(size_t n) {
    if (n == 0) return NULL;
    long long* fibArray = (long long*)malloc((n + 1) * sizeof(long long));
    fibArray[0] = 0;
    fibArray[1] = 1;
    for (int i = 2; i <= n; ++i) {
        fibArray[i] = fibArray[i - 1] + fibArray[i - 2];
    }
    return fibArray;
}

解析: 这里动态开辟了 N+1 个 long long 类型的空间用于存储数列。根据大 O 阶推导方法,空间复杂度为 O(N)。

4. 阶乘递归

// 计算阶乘递归 Fac 的空间复杂度?
long long Fac(size_t N) {
    if (N == 0) return 1;
    return Fac(N - 1) * N;
}

解析: 递归调用了 N 次,每次调用都会在栈上开辟一个新的栈帧。每个栈帧使用了常数个空间(保存 N 和返回地址等)。总共开辟了 N 个栈帧,因此空间复杂度为 O(N)。

🎯 递归算法的空间复杂度 = 单次递归的空间复杂度 × 递归深度

递归栈帧示意图


总结

本文系统性地讲解了算法空间复杂度的核心知识,旨在帮助读者建立一套分析算法效率的完整框架。通过对比不同场景下的代码实现,可以看出空间复杂度的计算关键在于统计额外临时占用的变量个数或内存块大小。掌握这些规则,有助于在实际开发中写出更节省资源的程序。

目录

  1. 大 O 的渐进表示法回顾
  2. 一、算法的空间复杂度
  3. 二、常见空间复杂度计算举例
  4. 1. 动态开辟二维数组
  5. 2. 冒泡排序
  6. 3. 斐波那契数列(非递归)
  7. 4. 阶乘递归
  8. 总结

更多推荐文章

查看全部
  • Python 打包编译工具 PyInstaller 与 Nuitka 特性对比
  • RAG 评估指南:从检索到生成的 LLM 性能评估方法
  • Web 开发者实战:多模态 Agent 图像识别与全栈处理方案
  • 利用 MCP Server - Figma AI Bridge 一键生成前端代码
  • Python 缓存策略:从 dict 到 LRU 与分布式实战
  • Spring Web MVC 入门:注解用法、参数传递与 Postman 测试
  • Milvus 部署架构选型与 Linux Docker 实战:Standalone 模式及 WebUI 使用
  • MiniMax 海螺 AI 视频:图文生视频功能与 API 接入指南
  • 91n 边缘计算设备部署轻量 TensorFlow 模型实战
  • 绿联云 NAS 配置 WebDAV 实现公网文献同步
  • Cursor 集成 MCP 服务实战指南
  • Python 实现 Windows 开机自动启动程序及打开网页
  • Llama-3.2-3B 在 Ollama 中配置长上下文与生成限制
  • MATLAB/Simulink 三相桥式全控整流电路仿真与波形分析
  • AI工具链:Gradio演示界面
  • 具身导航 VLN 最新论文汇总 | Vision-and-Language Navigation
  • 在 MySQL 中查找重复值
  • 当前主流大模型盘点及国内企业选型指南
  • 基于 KaiwuDB 与 CodeArts 智能体的智能家居本地化数据处理方案
  • Kubernetes 云原生实践:.NET Core 与 Java 深度对比

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online