【数据结构手札】空间复杂度详解:概念 | 习题

【数据结构手札】空间复杂度详解:概念 | 习题
在这里插入图片描述


🌈个人主页:聆风吟
🔥系列专栏:数据结构手札
🔖少年有梦不应止于心动,更要付诸行动。


文章目录

📚专栏订阅推荐

专栏名称专栏简介
C++藏宝阁本专栏聚焦学习阶段核心知识点,深耕基础与实战,干货笔记持续更新,和大家共学共进,夯实编程功底。
数据结构手札本专栏主要是我的数据结构入门学习手札,记录个人从基础到进阶的学习总结。
数据结构手札・刷题篇本专栏是《数据结构手札》配套习题讲解,通过练习相关题目加深对算法理解。

📋往期回顾:复杂度概念

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

时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间。在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。

📋往期回顾:大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;}

解析: 实例1在此处开辟的是一个二维数组,数组有n行,每行分别有1,2,3,…n列,所以是n(n + 1)/2个元素空间,空间复杂度为O(n^2)

2️⃣实例二

// 计算BubbleSort的空间复杂度?voidBubbleSort(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;}}

解析: 实例2使用了常数个额外空间,分别是[ end,exchange,i ]。根据大O阶的推导方法很容易得出,BubbleSort空间复杂度为 O(1)

3️⃣实例三

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

解析:实例3动态开辟了N+1个空间,根据大O阶的推导方法很容易得出,Fibonacci空间复杂度为 O(N)

4️⃣实例四

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

解析:实例4递归调用了N次,开辟了N个栈帧,每个栈帧使用了常数个空间。空间复杂度为O(N)

🎯递归算法的空间复杂度 = 单次递归的空间复杂度 * 递归次数
在这里插入图片描述

📝全文总结

本文系统性地讲解了算法空间复杂度的核心知识,旨在帮助读者建立一套分析算法效率的完整框架。

今天的干货分享到这里就结束啦!如果觉得文章还可以的话,希望能给个三连支持一下,聆风吟的主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的最大动力!

在这里插入图片描述

Read more

Spring Boot AOP (四)与事务、异常处理交互

Spring Boot AOP (四)与事务、异常处理交互

博主社群介绍: ① 群内初中生、高中生、本科生、研究生、博士生遍布,可互相学习,交流困惑。 ② 热榜top10的常客也在群里,也有数不清的万粉大佬,可以交流写作技巧,上榜经验,涨粉秘籍。 ③ 群内也有职场精英,大厂大佬,跨国企业主管,可交流技术、面试、找工作的经验。 进群免费赠送写作秘籍一份,助你由写作小白晋升为创作大佬,进群赠送ZEEKLOG评论防封脚本,送真活跃粉丝,助你提升文章热度。 群公告里还有全网大赛约稿汇总/博客提效工具集/ZEEKLOG自动化运营脚本 有兴趣的加文末联系方式,备注自己的ZEEKLOG昵称,拉你进群,互相学习共同进步。 文章目录 * Spring Boot AOP (四)与事务、异常处理交互 * 1. 引言 * 2. @Transactional 与 AOP 结合 * 2.1 核心机制 * 2.2

By Ne0inhk

从零开始构建 ThinkPHP 8 多应用架构的完整指南

ThinkPHP 8 多应用模式完整教程 从零开始构建 ThinkPHP 8 多应用架构的完整指南 📖 目录 * 1. 什么是多应用模式 * 2. 多应用模式安装与配置 * 3. 目录结构规划 * 4. 路由配置 * 5. 服务层架构 * 6. 模型层共享 * 7. 缓存配置 * 8. 中间件配置 * 9. 异常处理 * 10. 数据库配置 * 11. 视图配置 * 12. 公共类库 * 13. 事件系统 * 14. 验证器共享 * 15. 跨应用调用 * 16. 最佳实践 * 17. 常见问题 1. 什么是多应用模式 1.1 概念说明 多应用模式是指在一个 ThinkPHP 项目中,

By Ne0inhk
PostgreSQL动态分区裁剪技术:查询性能优化解析(2026年版)

PostgreSQL动态分区裁剪技术:查询性能优化解析(2026年版)

PostgreSQL动态分区裁剪技术:从原理到实战的查询性能优化 一、引言 1.1 研究背景与意义 随着企业数据量从TB级向PB级演进,数据库管理系统面临着严峻的挑战。PostgreSQL作为一款功能强大的开源关系型数据库,凭借其高度的可扩展性和标准兼容性,在金融、电商、物联网等领域得到了广泛应用。然而,在处理海量数据时,如何通过分区裁剪技术精准定位目标数据,避免无关分区的无效扫描,已成为查询性能优化的关键突破口。 在实际应用中,许多场景对查询性能有着极高要求。以电商行业为例,订单数据量庞大,每天可能产生数百万甚至数千万条订单记录。在进行订单查询、统计分析等操作时,如果不能有效利用分区裁剪技术,查询可能会耗费大量时间,严重影响用户体验。又如在金融领域,交易数据的实时查询对于风险控制至关重要,动态分区裁剪技术能够帮助金融机构快速获取所需数据。 1.2 研究目标与范围 本文旨在深入研究PostgreSQL声明式分区表的动态裁剪机制,通过结合源码分析与实际案例,系统地阐述其实现原理、优化策略及性能影响因素。研究目标包括: * 从源码层面深入剖析动态分区裁剪的实现原理 *

By Ne0inhk
Java-Spring入门指南(二十三)俩万字超详细讲解利用IDEA手把手教你实现SSM(Spring + SpringMVC + MyBatis)整合,并构建第一个SSM基础系统

Java-Spring入门指南(二十三)俩万字超详细讲解利用IDEA手把手教你实现SSM(Spring + SpringMVC + MyBatis)整合,并构建第一个SSM基础系统

Java-Spring入门指南(二十三)俩万字超详细讲解利用IDEA手把手教你实现SSM(Spring + SpringMVC + MyBatis)整合,并构建第一个SSM基础系统 * 前言 * 一、初始化项目与导入Maven依赖 * 二、接着导入Spring + SpringMVC + MyBatis相关的依赖包 * 1. 导入依赖包 * 1. 核心依赖包 * 2. 所有依赖包一览 * 三、创建SSM项目文件架构 * 1. 搭建web环境 * 2. 创建并链接数据库,并在完成MyBatis链接 * 四、运行测试 * 5.1 配置Tomcat 前言 * 在上一篇博客中,我们理清了SSM整合的核心逻辑——让Spring作为“总指挥”统一管理组件,SpringMVC处理请求,MyBatis操作数据库,解决单独使用框架时“衔接繁琐、配置混乱”的痛点。但“理论懂了”还不够,实际开发中最关键的是“把代码跑通”

By Ne0inhk