【数据结构】初探时间与空间复杂度:算法评估与优化的基础
🚩纸上得来终觉浅, 绝知此事要躬行。
🌟主页:June-Frost
🚀专栏:数据结构
🔥该文章主要了解算法的时间复杂度与空间复杂度等相关知识。
目录:
- 🌏 时间复杂度
- 🔭 一些例子
- 🌎 空间复杂度
- ❤️ 结语
📗时间复杂度和空间复杂度是计算机科学中用来评估算法效率的两个重要概念。它们分别描述了算法在执行时间和额外内存使用方面的需求,帮助我们了解算法在处理输入数据时所需的资源。在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。
🌏 时间复杂度
在计算机科学中,算法的时间复杂度是一个函数,用于度量算法执行时间的指标。因为一个算法所花费的时间与其中语句的执行次数成正比例,所以可以认为在算法中的基本操作的执行次数,为算法的时间复杂度。
计算时间复杂度时,其实并不一定要计算精确的执行次数,只需要大概执行次数即可。
✨表示方式为大O的渐进表示法,记作T(n) = O(f(n)),其中T(n)表示算法执行时间,f(n)表示问题规模n的函数。具体来说,当n趋近于无穷大时,算法执行时间的增长趋势与f(n)的增长趋势相同的最高阶项即为该算法的时间复杂度。
✨推导方式:
- 用常数1取代运行时间中的所有加法常数。
- 运行次数函数中,只保留最高阶项。
- 只关注数量级,而忽略常数因子,即去掉系数。
🔭 一些例子
①
void exampleAlgorithm(int N)
{for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){printf("This is O(n^2) operation.\n");}}for (int k = 0; k < 2 * N; k++){printf("This is O(n) operation.\n");}for (int M = 5; M > 0; M--){printf("This is O(1) operation.\n");}}
这个例子的函数表达式为 F(N) = N2 +2*N + 5,随着N的不断增加,N2 对最终结果具有决定性的作用,所以N2就是它的量级,运用大O的渐进表示法就可以表示为O(N2) 。
②
void exampleAlgorithm(int N)
{for (int k = 0; k < 2 * N; k++){printf("This is O(n) operation.\n");}for (int M = 5; M > 0; M--){printf("This is O(1) operation.\n");}}
如果没有了嵌套,这个函数的表达式就变成了 F(N) = 2*N + 5,这样随着N的增加,有决定性效果的就是2 * N,但是为了简化复杂度的表示,并突出算法随输入数据规模增长的趋势,又因为系数对于这种增长趋势的影响较小,所以一般需要去除系数,时间复杂度为O(N) 。
③
void exampleAlgorithm()
{for (int M = 1000; M > 0; M--){printf("This is O(1) operation.\n");}}
如果只有常数阶,那么就可以直接表示为O(1) 。
⚠注意:
📙通过上面这些例子,我们会发现大O的渐进表示法去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数,但是有些算法的时间复杂度存在最好、平均和最坏情况,在实际中一般关注的是算法的最坏运行情况。
④冒泡排序:
void bubble_sort(int* arr, int sz)
{int i = 0;for (i = 0; i < sz - 1; i++){int flag = 1; //标记int j = 0;for (j = 0; j < sz - 1 - i; j++){if (arr[j] > arr[j + 1]){flag = 0;int temp = 0;temp = arr[j + 1];arr[j + 1] = arr[j];arr[j] = temp;}}if (flag == 1)//如果等于1表示数组数据已经有序{break;}}
}
对于冒泡排序,最好的情况就是本身有序,只需遍历比较一遍数组即可,这时的时间复杂度为O(N),最坏的情况就是逆序,排好第一个数据需要比较N-1次,排好第二个数据需要比较N-2次,…,排好倒数第二个数据需要比较1次,最后一个数据不需要比较,将次数相加就是 [N*(N-1)] / 2,量级为N2,时间复杂度就是O(N2),最终的时间复杂度需要取最坏情况,即O(N2)。
⑤二分查找
int BinarySearch(int* arr, int sz, int k)
{int left = 0;int right = sz - 1;while (left <= right){int mid = (right + left) / 2;if (arr[mid] < k){left = mid + 1;//调整范围}else if (arr[mid] > k){right = mid - 1;//调整范围}else{return mid;}}return -1;
}
📘最好的情况是第一次查找就找到了,为O(1)。
📙最坏的情况为数据在边缘或者数组中没有要查找的数据:
一般将 log2N 简写为logN ,所以时间复杂度为 O(logN)。
⑥ 阶乘
long long Factorial(size_t N)
{if (N == 0)return 1;return Factorial(N - 1) * N;
}
调用函数需要创建栈帧,传入参数后,会调用Factorial(N) ,再调用Factorial(N-1),不断调用,直到调用到Factorial(0),共调用了N+1次,每次调用的时间复杂度为O(1),所以最终的时间复杂度为O(N) 。
⑦ 斐波那契数
long long Fibonacci(size_t N)
{if (N <= 2)return 1;return Fibonacci(N - 1) + Fibonacci(N - 2);
}
将 20 一直加到 2(n-2) ,算法的量级为2n,虽然实际上右边的分支会缺少一部分,但是不会影响到这个量级。
🌎 空间复杂度
空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度 。空间复杂度算的是变量的个数,计算规则基本跟实践复杂度类似,也使用大O渐进表示法。
⚠注意:
📙函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,因此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定。
① 冒泡排序
冒泡排序属于原地排序,在排序过程中并没有使用额外的空间来帮助排序,那些用来循环的变量,可以看作常数阶,所以冒泡排序的空间复杂度为O(1) 。
②阶乘
long long Factorial(size_t N)
{if (N == 0)return 1;return Factorial(N - 1) * N;
}
阶乘可以看作额外开辟了N个栈帧,每个栈帧空间内部没有额外创建空间,即每个栈帧空间为O(1),最终的空间复杂度为O(N) 。
③斐波那契数
long long Fibonacci(size_t N)
{if (N <= 2)return 1;return Fibonacci(N - 1) + Fibonacci(N - 2);
}
栈帧空间是可以复用的,所以通常用计算算法所占用的内存空间的最大值来评估算法的空间复杂度,只需要知道在递归中会最大开辟多少栈帧空间就可以进行计算,这个算法最多开辟栈帧数量的量级为N,每个栈帧空间为O(1),所以最终的空间复杂度为O(N)。
❤️ 结语
文章到这里就结束了,如果对你有帮助,你的点赞将会是我的最大动力,如果大家有什么问题或者不同的见解,欢迎大家的留言~
相关文章:

【数据结构】初探时间与空间复杂度:算法评估与优化的基础
🚩纸上得来终觉浅, 绝知此事要躬行。 🌟主页:June-Frost 🚀专栏:数据结构 🔥该文章主要了解算法的时间复杂度与空间复杂度等相关知识。 目录: 🌏 时间复杂度🔭…...

SpringCloud Alibaba - Sentinel 限流规则(案例 + JMeter 测试分析)
目录 一、Sentinel 限流规则 1.1、簇点链路 1.2、流控模式 1.2.1、直接流控模式 1.2.2、关联流控模式 a)在 OrderController 中新建两个端点. b)在 Sentinel 控制台中对订单查询端点进行流控 c)使用 JMeter 进行测试 d)分…...
uniapp 条件编译 APP 、 H5 、 小程序
一、#ifdef、#ifndef、 #endif三者的区别、 标识作用#ifdef仅在某个平台上使用#ifndef在除了这个平台的其他平台上使用(非此平台使用)#endif结束条件编译 二、平台标识 标识平台APP-PLUS5AppMP微信小程序/支付宝小程序/百度小程序/头条小程序/QQ小程序MP-WEIXIN微…...

深度学习——权重衰减(weight_decay)
深度学习——权重衰减(weight_decay) 文章目录 前言一、权重衰减1.1. 范数与权重衰减1.2. 高维线性回归1.3. 从零开始实现1.3.1.初始化模型参数1.3.2. 定义L₂范数惩罚1.3.3. 定义训练代码实现1.3.4. 不管正则化直接训练1.3.5. 使用权重衰减 1.4. 简洁实现 总结 前言…...
nignx如何部署让前端不用清缓存就可以部署
在Nginx中,可以使用以下方法来部署前端应用程序,使前端用户无需清空缓存即可进行部署: 1、使用版本号:在前端应用程序的构建过程中,可以添加一个独特的版本号到应用程序的名称中。每次部署时,将版本号更新…...

CSS3实现动画加载效果
<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>加载效果</title><link rel"style…...
springboot定时任务Scheduled使用和弊端分析
1.springboot定时任务Scheduled使用说明: (1)创建定时任务类 import com.one.utils.DateUtil; import org.springframework.beans.factory.annotation.Autowired; import...

openGauss学习笔记-93 openGauss 数据库管理-访问外部数据库-oracle_fdw
文章目录 openGauss学习笔记-93 openGauss 数据库管理-访问外部数据库-oracle_fdw93.1 编译oracle_fdw93.2 使用oracle_fdw93.3 常见问题93.4 注意事项 openGauss学习笔记-93 openGauss 数据库管理-访问外部数据库-oracle_fdw openGauss的fdw实现的功能是各个openGauss数据库及…...

【Git】Git下载安装环境配置 下载速度慢的解决方案
这里写自定义目录标题 介绍一、下载官网下载镜像站 二、安装安装成功 三、Git三种界面介绍Git cmd界面展示git bash界面展示git GUI界面展示 四、环境配置配置流程1、打开环境变量界面2、添加环境变量 /删除环境变量3、在变量中找到Git\cmd的值就表示配置成功4、没有找到点击新…...

常见源协议介绍
开源协议(Open Source License)是一种法律文档,用于规定如何使用、修改和分发开源软件和其他开源项目的规则和条件。这些协议允许创作者或组织将其创造的代码或作品以开放源代码的形式共享给他人,以促进协作、创新和知识共享。常见…...

大数据概述(林子雨慕课课程)
文章目录 1. 大数据概述1.1 大数据概念和影响1.2 大数据的应用1.3 大数据的关键技术1.4 大数据与云计算和物联网的关系云计算物联网 1. 大数据概述 大数据的四大特点:大量化、快速化、多样化、价值密度低 1.1 大数据概念和影响 大数据摩尔定律 大数据由结构化和非…...

ES6 class类关键字super
super关键字 在 JavaSCript 中,能通过 extends 关键字去继承父类 super 关键字在子类中有以下用法: 当成函数调用 super() 作为 "属性查询" super.prop 和 super[expr] super() super 作为函数调用时,代表父类的构造函数。 ES6 要求…...

C++并发与多线程(4) | 传递临时对象作为线程参数的一些问题Ⅰ
一、陷阱1 写一个传递临时对象作为线程参数的示例: #include <iostream> #include <vector> #include <thread> using namespace std;void myprint(const int& i, char* pmybuf) {cout << i << endl;cout << pmybuf << endl;r…...

CentOS Integration SIG 正式成立
导读CentOS 董事会已批准成立 CentOS Integration Special Interest Group (SIG)。该小组旨在帮助那些在 Red Hat Enterprise Linux (RHEL) 或特别是其上游 CentOS Stream 上构建产品和服务的人员,验证其能否在未来版本中继续运行。 红帽 RHEL CI 工程师 Aleksandr…...

智能AI系统源码ChatGPT系统源码+详细搭建部署教程+AI绘画系统+已支持OpenAI GPT全模型+国内AI全模型
一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统,支持OpenAI GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Chat…...

软考程序员考试大纲(2023)
文章目录 前言一、考试说明1.考试目标2.考试要求3.考试科目设置 二、考试范围考试科目1:计算机与软件工程基本知识1.计算机科学基础2.计算机系统基础知识3.系统开发和运行知识4.网络与信息安全基础知识5&am…...

【重拾C语言】七、指针(一)指针与变量、指针操作、指向指针的指针
目录 前言 七、指针 7.1 指针与变量 7.1.1 指针类型和指针变量 7.1.2 指针所指变量 7.1.3 空指针、无效指针 7.2 指针操作 7.2.1 指针的算术运算 7.2.2 指针的比较 7.2.3 指针的递增和递减 7.3 指向指针的指针 前言 指针是C语言中一个重要的概念正确灵活运用指针 可…...
Kafka源码简要分析
目录 一、生产者的初始化流程 二、生产者到缓冲队列的流程 三、Sender拉取数据到Kafka流程 四、消费者初始化 五、主题订阅原理 六、消费者抓取数据原理 七、消费者组初始化 八、消费者组消费流程 九、提交offset原理 一、生产者的初始化流程 首先获取事务id和客户端…...
react 按住ctrl键,点击时会出现菜单的问题修复
问题描述:我需要按住crtl键,然后鼠标点击后做一些逻辑操作,但是出现如下问题 问题一:按住ctrl键后,点击时不触发click事件,只触发 mousedown和mouseup事件。 问题二:按住ctrl键点击时出现菜单…...

【虚拟机栈】
文章目录 1. 虚拟机栈概述2. 局部变量表(Local Variables)3. 操作数栈4. 动态链接4.1 方法的调用:解析与分配 5. 方法返回地址6. 栈的相关面试题 1. 虚拟机栈概述 每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个的栈帧(Stack Frame…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...