2.数据结构--空间复杂度

news2024/11/18 1:33:38

文章目录

  • 一、空间复杂度讲解
  • 二、计算下列经典例题的空间复杂度
    • 1.冒泡排序的空间复杂度 O(1)
    • 2.斐波那契递归的空间复杂度 O(N)
    • 3.计算阶乘递归的空间复杂度 O(N)
  • 三、时间复杂度和空间复杂度的对比
  • 四、常见的函数的时间复杂度和空间复杂度的总结


一、空间复杂度讲解

1.空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用额外的存储空间大小的量度
2.空间复杂度算的是变量的个数
3.函数运行时所需要的栈空间(存储参数,局部变量,一些寄存器信息等)在编译期间就已经确定好了,因此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定(栈帧里面保存的寄存器,形参都可算进空间复杂度,都算常数个)

二、计算下列经典例题的空间复杂度

1.冒泡排序的空间复杂度 O(1)

// 计算BubbleSort的空间复杂度?O(1)
void BubbleSort(int* a, int n)
{//a指向一个数组
	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;
	}
}

解析:
注意:用到数组,数组有n个空间,不算冒泡排序的消耗,并不是因为排序而开辟的空间,是本来就有,排序对数组的n个空间进行处理
函数里面开辟的空间end,exchange都是常数个,所以空间复杂度是O(1)

2.斐波那契递归的空间复杂度 O(N)

long long Fib(size_t N)
{
 if(N < 3)
 return 1;
 
 return Fib(N-1) + Fib(N-2);
}

解析:
在这里插入图片描述
关于上面解析中提到的 栈帧销毁后,再调用函数,会复用栈帧的解释如下:
(1)问题:销毁了栈帧还怎么能够复用?
空间的销毁,栈帧的销毁,变量的销毁,malloc之后的free,他们都不是指把空间整没了,而是归还这块空间的使用权
(2) 内存空间属于操作系统的进程,而调用函数建立栈帧,或者malloc都是去对应的区域申请空间的使用权。
销毁指的是将这块空间的使用权还给进程,而这块空间还可以给别人用
(3)之所以会复用,首先是因为栈帧是向下建立的,上面是高地址,下面是低地址,而堆是向上生长的,malloc的空间就在堆。
结合本题解释: 调用该函数的时候建立栈帧,调用完毕销毁该栈帧,也就是归还使用权,在此之后紧接着调用函数,又建立栈帧,由于栈帧是向下建立的,所以申请的空间还是刚刚使用过并归还的那块空间,也就是说这个栈帧的重复使用。
注意:在堆上两次malloc分配的空间的地址可能是不一样的

关于堆;
1.堆被称为"向上生长"是指在内存地址空间中,堆的分配方向是从低地址向高地址逐渐增长的。这意味着,随着堆中内存块的分配,新分配的内存块通常会位于已分配内存块的上方。
2.在一般情况下,如果连续多次调用malloc分配内存块,这些内存块的起始地址通常是递增的,即后续分配的内存块的地址比前面分配的内存块的地址要大。
当使用连续的malloc调用时,堆管理器会在堆内存中寻找足够的空闲空间来满足每个分配请求。由于管理机制和内存对齐的考虑,以及其他可能的因素(如堆的碎片化),每次分配的起始地址可能会有所不同。这意味着在实际情况下,即使连续调用多次malloc,返回的内存块的起始地址也可能不同。
因此,一般情况下,连续的malloc调用返回的内存块起始地址有可能不同,但是它们通常是递增的。这是由于堆管理器的分配机制和内存对齐的要求所决定的

(4)进程—(类比)—>酒店
申请内存–> 开房
销毁内存–> 退房
越界 --> 开了一个房间,但通过一些手段比如挖洞还进入了另一个房间
野指针 --> 开房自己偷偷配置了钥匙,再把房卡退了之后,拿着自己配的钥匙去把 房间打开住进去不是你的房间,这时报警相当于系统崩溃
(5)进程地址空间分几个区域:
(局部变量)
(malloc的空间)
静态区 (全局数据和静态数据)
常量区 (常量)
(6)在这里插入图片描述

3.计算阶乘递归的空间复杂度 O(N)

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

	return Fac(N - 1) * N;
}

递归调用了N次,开辟了N个栈帧,每个栈帧里没有开辟额外的空间,每个栈帧里都是常数个空间
在这里插入图片描述

三、时间复杂度和空间复杂度的对比

时间一去不复返,时间是累积计算的、
空间是可以重复利用的,不累积计算

四、常见的函数的时间复杂度和空间复杂度的总结

冒泡排序 时间复杂度 O(N^2) 空间复杂度O(1)
斐波那契递归 时间复杂度 O(2^N) 空间复杂度O(N)
二分查找 时间复杂度 O( log2(N) )
阶乘递归 时间复杂度 O(N) 空间复杂度O(N)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/756759.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

复习第五课 C语言-初识数组

目录 【1】初识数组 【2】一维数组 【3】清零函数 【4】字符数组 【5】计算字符串实际长度 练习&#xff1a; 【1】初识数组 1. 概念&#xff1a;具有一定顺序的若干变量的集合 2. 定义格式&#xff1a; 数组名 &#xff1a;代表数组的首地址&#xff0c;地址常量&…

【iOS】ARC内存管理

内存管理 内存管理的思考方式iOS底层内存管理方式1. tagged pointer2. on-pointer iSA--非指针型iSA3. SideTables&#xff0c;RefcountMap&#xff0c;weak_table_t 内存管理有关修饰符__strong修饰符对象的所有者和对象的生命周期__strong对象相互赋值方法参数中使用__strong…

LeetCode 热题 100(一):哈希。49. 字母异位词分组、128. 最长连续序列。

LeetCode100链接&#xff1a;LeetCode 热题 100 - 学习计划 - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台 一、49. 字母异位词分组 题目要求&#xff1a; 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。…

【ACM】—蓝桥杯大一暑期集训Day2

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;目前正在学习C/C、Java、算法等方向&#xff0c;一个正在慢慢前行的普通人。 &#x1f3c0;系列专栏&#xff1a;陈童学的日记 &#x1f4a1;其他专栏&#xff1a;CSTL&#xff…

10秒搞定!教你如何轻松压缩jpg格式图片大小!

大家在日常拍照时&#xff0c;都会发现拍摄出来的JPG图片体积比较大&#xff0c;使用和保存时都会比较麻烦。那么该怎样压缩图片大小呢&#xff1f; 首先&#xff0c;我们需要了解什么是JPG压缩。JPG是一种有损压缩格式&#xff0c;通过减少图像中的信息量来使文件大小缩小。使…

Java实现多文件上传及进度条提示-源码下载

1、方案概述 1、案例框架使用的是springmvc5.3.16版本,jackson使用的是2.13.3版本。 2、前端使用的是Layui2.8.11框架,这个框架上手较为容易。 3、使用关键类CommonsMultipartResolver和MultipartHttpServletRequest实现多文件捕获。 2、效果预览 【选择文件】 【上传过…

Android JNI线程的同步 (十三)

🔥 Android Studio 版本 🔥 🔥 了解线程同步的两个变量 🔥 pthread_mutex_t 互斥锁 线程的互斥: 目前存在两个线程 , 线程A和线程B, 只允许只有一个资源对临界资源进程操作 (大概意思就是 : A线程 进入操作临界资源的时候 , 那么 B线程 就要进行等待 . 等到 A线程…

感受C++模版的所带来的魅力,扎实基础,扩展思维

一、泛型编程思想 首先我们来看一下下面这三个函数&#xff0c;如果学习过了 C函数重载 和 C引用 的话&#xff0c;就可以知道下面这三个函数是可以共存的&#xff0c;而且传值会很方便void Swap(int& left, int& right) {int temp left;left right;right temp; } …

Nuxt.js--》解密Nuxt.js:构建优雅、高效的现代化Vue.js应用

博主今天开设Nuxt.js专栏&#xff0c;带您深入探索 Nuxt.js 的精髓&#xff0c;学习如何利用其强大功能构建出色的前端应用程序。我们将探讨其核心特点、灵活的路由系统、优化技巧以及常见问题的解决方案。无论您是想了解 Nuxt.js 的基础知识&#xff0c;还是希望掌握进阶技巧&…

【C++】Eigen库实现最小二乘拟合

前言 入职第二周的任务是将导师的Python代码C化&#xff0c;发现Python中存在Numpy包直接调用np.polyfit就好了&#xff0c;但是C不存在需要造轮子。 #include <iostream> #include <cmath> #include <vector> #include <Eigen/QR> #include "x…

re学习(15)BUUCTF 2019红帽杯easyRe(寻找数据+xor问题)

参考视频&#xff1a; 【BUUCTF】每天一个CTF11“2019红帽杯easyRe”_哔哩哔哩_bilibili &#xff08;本人觉得看视频比看博客效率能提高十倍&#xff0c;呜呜呜&#xff0c;还是视频香~~~与君共勉&#xff09; 下载地址&#xff1a; BUUCTF在线评测 前言&#xff1a;虽然…

Spring Boot集成Redisson实现分布式锁

Spring Boot集成Redisson实现分布式锁 在分布式系统中&#xff0c;为保证数据的一致性和并发访问的安全性&#xff0c;我们经常会使用分布式锁来协调多个节点之间对共享资源的访问。Redisson是一个基于Redis的Java驻内存数据网格&#xff08;In-Memory Data Grid&#xff09;和…

【C++】string类模拟

文章目录 成员变量和查看接口迭代器&#xff08;读和读写&#xff09;operator[]&#xff08;读和读写&#xff09;c_str()size() 构造函数用字符串构造用对象构造&#xff08;两种方法&#xff09;析构 赋值运算符重载扩容和调整reserve()resize()clear() 增删查改push_back()…

C++的switch函数用法

一个 switch 语句允许测试一个变量等于多个值时的情况。每个值称为一个 case&#xff0c;且被测试的变量会对每个 switch case 进行检查。 语法 C 中 switch 语句的语法&#xff1a; switch(expression){ case constant-expression : statement(s); break; // 可选的 case c…

Redis数据类型 — Zset

目录 Zset内部设计 跳表哈希表 ZipList ZSet中每一个元素都需要指定一个score值和member值&#xff1a;<1> 可以根据score值排序后<2> member必须唯一<3> 可以根据member查询分数 Zset内部设计 因此&#xff0c;zset底层数据结构必须满足键值存储、键必…

AutoCAD如何通过C#进行插件开发?

文章目录 0.引言1.开发工具准备2.VS&#xff08;C#&#xff09;创建插件3.使用插件 0.引言 AutoCAD是一款广泛应用于工程设计和建筑行业的计算机辅助设计软件。通过使用C#语言进行插件开发&#xff0c;可以扩展AutoCAD的功能&#xff0c;实现定制化的需求。插件可以实现自动化绘…

linux之Ubuntu系列(-)

单用户和多用户 注意事项 Linux 系统 中区分大小写的 Window 系统 不分区大小写的

1.Java语言概述

1.1概述 JDK(Java development kit)java开发工具包 JDK是提供Java开发人员使用的&#xff0c;其中包含java的开发工具&#xff0c;包括JRE,所以安装JDK&#xff0c;就不需要安装JRE了 其中编译工具javac.exe、打包工具jar.exe JRE(Java Runtime environment) java运行环境 包括…

android11 input 事件 1 初始化

system_server 初始化InputManagerService // SystemServer.java private void startOtherServices(NonNull TimingsTraceAndSlog t) {t.traceBegin("startOtherServices");// 初始化InputManagerServicet.traceBegin("StartInputMana…

让机器学习不再是过门不入,带您一起详解机器学习(机器学习 Machine Learning 研习之一)

什么是机器学习&#xff08;Machine Learning&#xff09;&#xff1f; 机器学习是]赋予计算机学习能力的研究领域 无需明确编程。 ——阿瑟塞缪尔&#xff0c;1959 计算机程序可以从关于某些任务的经验 E 中学习 T 和一些绩效衡量 P&#xff0c;如果其在 T 上的绩效按 P 衡量&…