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

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


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


文章目录

📚专栏订阅推荐

专栏名称专栏简介
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

【C++】深入浅出“图”——最短路径算法

【C++】深入浅出“图”——最短路径算法

文章目录 * 一、Dijkstra算法 * 二、Bellman_Ford算法 * 三、Floyd_Warshall算法 一、Dijkstra算法 最短路径问题是指,从在带权的有向图中从某一顶点出发,找到通往另一顶点的最短路径,“最短”指的是沿路径各边的权值总和最小。 Dijkstra算法是单源最短路径的经典贪心算法,只能用于没有负权的图。它从起点出发,每次选当前距离最小且未确定最短路径的节点,用它去松弛(更新)所有邻接点的最短路径估计值,标记该节点为 “已确定”,重复此过程直到所有节点处理完毕,最终得到起点到图中所有节点的最短路径。 // src是选定的起点,dist记录起点到各点的最短路径,pPath记录到每个点的最短路径的前驱顶点下标voidDijkstra(const V& src, vector<W>& dist, vector<int>& pPath){ size_t srci =GetVertexIndex(

By Ne0inhk
备战蓝桥杯----C/C++组 (一)所需C++基础知识(上)

备战蓝桥杯----C/C++组 (一)所需C++基础知识(上)

个人主页: wengqidaifeng ✨永远在路上,永远向前走 个人专栏: 数据结构 C语言 嵌入式小白启动! 重要OJ算法题详解 文章目录 * 前言 * 一. 分析大纲,了解所需 * 1. 大纲显示内容 * 2、组别划分与难度关系 * 3、知识点结构分析(按组别) * 3.1 大学C组:基础入门阶段 * 3.2 大学B组:中级提高阶段 * 3.3 大学A组 / 研究生组:高级挑战阶段 * 4.难度系数说明 * 二. C++基础语法(上):从零开始的编程基石 * 1.前言 * 2.开发环境搭建 - DevC++的安装与使用 * 2.1

By Ne0inhk
2025年9月GESP真题及题解(C++八级): 选择题和判断题(题解)

2025年9月GESP真题及题解(C++八级): 选择题和判断题(题解)

2025年9月GESP真题及题解(C++八级): 选择题和判断题(题解) 第 1 题 小杨想点一杯奶茶外卖,但还差 5 元起送。于是,小杨决定点一些小料。可选的小料包括:珍珠 1 元、椰果 2 元、奶冻 3 元、奶盖 4 元。每种小料最多点 1 份。请问共有多少种满足起送条件的点小料方案?( )。 A. 16 B. 10 C. 9 D. 7 答案:C 题解:小料有4种,每种可选或不选,总共有 24=1624=16 种组合。总价分别为:

By Ne0inhk
【C++从零实现Json-Rpc框架】第六弹——服务端模块划分

【C++从零实现Json-Rpc框架】第六弹——服务端模块划分

一、前言         在第五弹中我们对项目的功能进行了讲解,接下来我们就服务端的角度,来设计对应模块,帮助服务端实现项目的三个功能: ●  rpc调用 ● 服务的注册与发现以及服务的下线/上线通知 ● 消息的发布订阅 二、正文 1. 服务端的功能需求 在进行服务端具体的模块划分之前,我们先来明确下服务端的功能需求 ● 基于网络通信接受客户端的请求,提供rpc服务 ● 基于网络通信接受客户端的请求,提供服务注册与发现,上线&下线通知 ●  基于网络通信接受客户端的请求,提供主题操作(创建/删除/订阅/取消),消息发布 2. 服务端的模块划分  基于上述的功能,我们对服务端可以划分出这么几个模块 ● Network:网络通信模块 ● Protocol: 应用层通信协议模块 ● Dispatcher:消息分发处理模块 ● RpcRouter: 远端调用路由功能模块 ● Publish-Subcriber: 发布订阅模块 ● Registry-Discovery:服务注册/发现/上线/下线功能模块 ● Server:

By Ne0inhk