空间复杂度

news2024/10/6 14:25:16

概念

空间复杂度:是对一个算法在运行过程中临时占用存储空间大小的量度。 

空间复杂度和时间复杂度的表示方法是一样的,也使用大O渐进表示法,计算规则基本相似。空间复杂度计算的并不是程序占用的字节大小,而是变量的个数。

大O符号(Big O notation):是用于描述函数渐进行为的数学符号。
推导大O阶方法:
1、用常数1取代运行时间中的所有加法常数。
2、在修改后的运行次数函数中,只保留最高阶项。
3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶

 例题解释

接下来就通过几道例题来更深入的了解一下空间复杂度吧。发车luo~

 

一(冒泡排序)

void Bubsort(int* arr, int nums)//nums是元素个数
{
	assert(arr);
	int i, j;
	for (i = 0; i < nums - 1; i++)//排序次数
	{
		int flag = 0;//判断
		for (j = 0; j < nums - 1 - i; j++)//一次排序
		{
			
			if (arr[j] > arr[j + 1])
			{
				flag = 1;
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
		if (flag == 0)
			break;
	}
}

这里是冒泡排序的执行,数组中有 nums 个元素,那空间复杂度是 O(n) 吗?

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

所以在执行函数之前,栈区已经为函数中的数组元素开辟好了固定大小的空间 ,故计算空间复杂度时,只考虑函数内部执行时所开辟的空间。因此函数中创建了常数个变量,即:O(1)


二(数组实现斐波那契数列)

int* Fib(size_t n)
{
	int* arr = (int*)malloc(n+1 * sizeof(int));
    assert(arr);
	arr[0] = 0;
	arr[1] = 1;
	for (int i = 2; i <= n; i++)
	{
		arr[i] = arr[i - 1] + arr[i - 2];
	}
	return arr;
}

此函数中往 arr 中动态开辟了 n+1 个整型的空间,即相当于 n+1 个变量。故:O(n)


三(递归实现阶乘)

int Fac(size_t n)
{
	if (n == 0)
		return 1;
	return n * Fac(n - 1);
}

在递归调用 n 次时,就会在重新创建 n 个栈帧,每个栈帧使用了常数个空间,即:O(n)

递归过程就是一个进栈和出栈的过程,当进入一个新函数时,进行入栈操作,把调用的函数和参数信息压入栈中;当函数返回时,执行出栈。 


四(递归实现斐波那契数列) 

int Fib(size_t n)
{
	if (n < 3)
		return 1;
	return Fib(n - 1) + Fin(n - 2);
}

 首先我们得了解一下斐波那契数列递归是如何执行的,首先 Fib(n)= Fib(n-1)+ Fib(n-2)此时的 Fib(n)是先调用 Fib(n-1)时就开始创建栈帧,重新进入函数,Fib(n-1)= Fib(n-2)+ Fib(n-3)此时 Fib(n-1)会调用 Fib(n-2)......直到调用到 Fib(2)时就函数返回,依次出栈。栈帧销毁,再递归调用右边的时会和左边重复使用同一个栈帧(即销毁的栈帧再次拿过来使用)

所以空间是可以重复利用的,不会累计计算。

当执行 Fib(3)时会调用Fib(2),Fib(2)调用结束时函数返回一个值,并且Fib(2)开辟的栈帧销毁,此时就开始调用Fib(1)故又会创建一个栈帧,正好刚刚Fib(2)销毁了一个栈帧空间,所以这里的 1 和 2 用的是同一个栈帧空间。依次分析可以很清楚的知道空间复杂度为:O(n)


详细分析同一个栈帧

void test1()
{
	int a = 1;
	printf("%p\n", &a);
}
void test2()
{
	int b = 0;
	printf("%p\n", &b);
}
int main()
{
	test1();
	test2();

	return 0;
}

 这里调用 test1 函数时创建了变量 a 此时就在栈区开辟空间,而出了 test1 函数,为变量 a 开辟的空间也就销毁了,再次调用 test2 时,同样创建变量,栈区开辟空间 而再次开辟的空间就是 test1 销毁的空间。(销毁并不是不能用这块空间,只是该空间的数据销毁,就像和没开辟过一样,是可以继续使用的)


 

 

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

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

相关文章

chatgpt+机器人控制器融合(一)

当今机器人技术面临的挑战&#xff0c;以及 ChatGPT 能提供的帮助 目前机器人的操作流是从工程师或技术用户开始&#xff0c;需要他们将任务需求转换为系统代码。工程师会处于工作流程的回路中&#xff0c;他们需要不断编写新的代码和规范来纠正机器人的行为。总得来说&#x…

Faster-RCNN代码解读4:辅助文件解读

Faster-RCNN代码解读4&#xff1a;辅助文件解读 前言 ​ 因为最近打算尝试一下Faster-RCNN的复现&#xff0c;不要多想&#xff0c;我还没有厉害到可以一个人复现所有代码。所以&#xff0c;是参考别人的代码&#xff0c;进行自己的解读。 ​ 代码来自于B站的UP主&#xff08;…

我的创作纪念日:Unity CEO表示生成式AI将是Unity近期发展重点,发布神秘影片预告

PICK 未来的AI技术将会让人类迎来下一个生产力变革&#xff0c;这其中也包括生成型AI的突破性革新。各大公司也正在竞相推出AIGC工具&#xff0c;其中微软的Copilot、Adobe的Firefly、Github的chatGPT等引起了人们的关注。然而&#xff0c;游戏开发领域似乎还没有一款真正针对性…

vector容器

1、vector简介 vector 和 arry 非常相似&#xff0c;唯一存在的不同是 vector 是动态分配内存空间&#xff0c;随着元素的增加空间自动增加&#xff0c;但是 arry 是静态的 wector&#xff1a;单端动态数组容器&#xff0c;只允许在一端进行操作 2、vector的使用 需要引进头…

PyTorch深度学习实战 | 基于多层感知机模型和随机森林模型的某地房价预测

简介&#xff1a; 在现实生活中&#xff0c;除了分类问题外&#xff0c;也存在很多需要预测出具体值的回归问题&#xff0c;例如年龄预测、房价预测、股价预测等。相比分类问题而言&#xff0c;回归问题输出类型为一个连续值&#xff0c;如下表所示为两者的区别。在本文中&…

打造高效自动化测试流程:Jenkins+Allure+Pytest环境搭建和实战

引言 自动化测试已经成为软件开发中不可或缺的一部分。而在自动化测试中&#xff0c;Jenkins、Allure和Pytest这三个工具的组合可以说是非常流行和实用的。 Jenkins作为持续集成工具&#xff0c;可以充分利用其丰富的插件体系来搭建自动化测试环境&#xff1b; Allure则为我们…

怎么把jpg转换成pdf格式?实用又简单的方法来了

在工作和学习中&#xff0c;我们常常需要发送一些重要的图片给别人&#xff0c;这些图片可能包含学习资料或者重要的文件内容。但是发送多个JPG图片既不方便又不直观&#xff0c;所以我们需要将它们转换成PDF格式&#xff0c;以便于发送和查看。如果你不知道如何进行JPG到PDF的…

UI学习路线图2023完整版(适合自学)

作为数字时代中不可或缺的职业之一&#xff0c;UI设计师在今天和未来都有着广阔的职业前景。UI设计师有高需求行业、薪资高、职位晋升空间大、多样化的工作机会、职业发展空间大等许多优势&#xff0c;也有很多小伙伴想自学UI设计&#xff0c;但是不知道自己怎么学&#xff0c;…

服务器节点之间 如何实现自动化文件同步?

大数据、云计算、物联网的发展&#xff0c;使得企业能够拥有的数据急剧增加。面对快速变化和增长的庞大数据&#xff0c;如何高效地管理、利用数据对于企业来说至关重要。 但是&#xff0c;数据传输模式单一、自动化程度低、传输效率低下等难题&#xff0c;阻碍着企业对其数字…

TensorFlow 1.x 深度学习秘籍:6~10

原文&#xff1a;TensorFlow 1.x Deep Learning Cookbook 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的形象&#xff0c;只关心如…

高级UI之Android事件分发机制原理及源码分析

前言 在 Android 中&#xff0c;事件分发机制是一块很重要的知识点&#xff0c; 掌握这个机制能帮你在平时的开发中解决掉很多的 View 事件冲突问题&#xff0c;这个问题也是面试中问的比较多的一个问题了&#xff0c;本篇就来总结下这个知识点。 事件分发原因 Android 中页…

RK3399平台开发系列讲解(外设篇)Camera OV13850配置过程

🚀返回专栏总目录 文章目录 一、DTS 配置二、驱动说明三、配置原理四、cam_board.xml沉淀、分享、成长,让自己和他人都能有所收获!😄 📢我们以 OV13850/OV5640 摄像头为例,讲解在该开发板上的配置过程。 一、DTS 配置 isp0: isp@ff910000 {…status = "okay&quo…

R-CNN(Region with CNN feature)

目录 1. 介绍 2. R-CNN 2.1 SS(Selective Search) 算法 生成候选框 2.2 CNN 提取特征 2.3 SVM 分类 非极大值抑制 2.4 回归器微调候选框 3. R-CNN 的缺点 1. 介绍 目标识别的发展历史如图 2. R-CNN RCNN 是两阶段目标检测的鼻祖&#xff0c;类似于深度学习开山之作Al…

第03章_流程控制语句

第03章_流程控制语句 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 本章专题与脉络 流程控制语句是用来控制程序中各语句执行顺序的语句&#xff0c;可以把语句组合成能完成一定功能的小逻辑模…

算法记录 | Day32 贪心算法

122.买卖股票的最佳时机II 贪心算法 思路&#xff1a; 把利润分解为每天为单位的维度&#xff0c;而不是从0天到第3天整体去考虑&#xff01; 那么根据prices可以得到每天的利润序列&#xff1a;(prices[i] - prices[i - 1])…(prices[1] - prices[0])。 如图&#xff1a;…

PyCharm+PyQt5+pyinstaller打包labelImg.exe

0 开头 labelImg是一款标注软件&#xff0c;作为一个开源项目&#xff0c;它的源码可以在github上找到。官方仓库地址为&#xff1a; https://github.com/heartexlabs/labelImg 小白安装时的最新版本编译出来的界面长这样&#xff1a; 之前在小白的博客里&#xff0c;也教过…

Spring学习5

一、代理模式 代理模式就是AOP的底层&#xff01; 1.代理模式的分类 静态代理动态代理2.静态代理 角色分析&#xff1a; 抽象角色&#xff1a;一般使用接口或者抽象类来解决真实角色&#xff1a;被代理的角色代理角色&#xff1a;代理真实角色后&#xff0c;一般会做一些附属操…

走进小程序【七】微信小程序【常见问题总结】

文章目录&#x1f31f;前言&#x1f31f;小程序登录&#x1f31f;unionid 和 openid&#x1f31f;关键Api&#x1f31f;登录流程设计&#x1f31f;利用现有登录体系&#x1f31f;利用OpenId 创建用户体系&#x1f31f;利用 Unionid 创建用户体系&#x1f31f;授权获取用户信息流…

JVM内存模型详解

JVM内存模型和Java内存模型都是面试的热点问题&#xff0c;名字看感觉都差不多&#xff0c;实际上他们之间差别还是挺大的。 通俗点说&#xff0c;JVM内存结构是与JVM的内部存储结构相关&#xff0c;而Java内存模型是与多线程编程相关mikechen。 什么是JVM JVM是Java Virtual …

【教学类-30-04】10以内减法题不重复(一页两份)(包括6以内、7以内、8以内、9以内、10以内减法题 只抽取25个)

作品展示 ——10以内不重复减法题 需求&#xff1a; 1、制作10以内减法题 材料准备&#xff1a; Word模板 代码展示&#xff1a; 6、7、8、9、10以内减法一页两份&#xff08;10以内减法一页两份&#xff08;6以内、7以内、8以内、9以内、10以内不重复减法题&#xff09; 时间…