【数据结构】复杂度讲解
目录
时间复杂度与空间复杂度::
1.算法效率
2.时间复杂度
3.空间复杂度
4.常见时间复杂度以及复杂度OJ练习
时间复杂度与空间复杂度::
什么是数据结构?
数据结构中是计算机存储,组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合.
什么是算法?
算法是定义良好的计算过程,它取一个或一组的值为输入,并产生一个或一组值作为输出.简单来说
算法就是一系列的计算步骤,用来将输入数据转化成输出结果.
例如:数据结构是在内存中管理数据——增删查改
数据库是在磁盘中管理数据——增删查改
B树用到二分查找算法 去重要用到搜索树
1.算法效率
算法在编写成可执行程序后,运行时需要耗费时间资源和空间(内存)资源,因此衡量一个算法的好坏
一般是从时间和空间两个维度来衡量的,即时间复杂度和空间复杂度.
时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间
在计算机发展的早期,计算机的存储容量很小,所以对空间复杂度很是在乎,但是经过计算机行业的
迅速发展,计算机的存储容量已经达到了很高的程度,所以我们如今已经不需要再特别关注一个算法的空间复杂度.
摩尔定律:集成电路上可以容纳的晶体管数目在大约每经过18个月便会增加一倍.
2.时间复杂度
时间复杂度的概念:
时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间.
一个算法执行所耗费的时间,从理论上来说是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道.
但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式.
一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作执行次数,为算法的时间复杂度.
即:找到某条语句与问题规模N之间的数学表达式,就是算出了该算法的时间复杂度.
void Func1(int N)
{int count = 0;for (int i = 0; i < N; ++i){for (int j = 0; j < N; ++i){++count;}}for (int k = 0; k < 2 * N; ++k){++count;}int M = 10;while (M--){++count;}printf("%d\n", count);
}
时间复杂度为:O(N^2)
void Func2(int N)
{int count = 0;for (int k = 0; k < 2 * N; ++k){++count;}int M = 10;while (M--){++count;}printf("%d\n", count);
}
时间复杂度为:O(N)
void Func3(int N, int M)
{int count = 0;for (int k = 0; k < M; ++k){++count;}for (int k = 0; k < N; ++k){++count;}printf("%d\n", count);
}
时间复杂度为:O(M+N)
void BubbleSort(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;}
}
时间复杂度为:O(N^2)
void Fun4(int N)
{int count = 0;for (int k = 0; k < 100; ++k){++count;}printf("%d\n", count);
}
时间复杂度为:O(1)
大O的渐进表示法:
大O符号是用于描述函数渐进行为的数学符号.
推导大O渐进表示法:
1.用常数1取代运行时间中的所有加法常数.
2.在修改后的运行次数函数中,只保留最高阶项.
3.如果最高阶系数存在且不是1,则去掉与这个项目相乘的常数,得到的结果就是大O阶.
算法的时间复杂度存在最好,最坏和平均情况:
最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数(下界)
例如:在一个长度为N的数组中搜索一个数据x
最好情况:1次找到
最坏情况:N次找到
平均情况:N/2次找到
在实际情况中关注的是算法的最坏运行情况,所以数组中搜索数据时间复杂度为O(N)
int BinarySearch(int* a, int n, int x)
{assert(a);int begin = 0;int end = n - 1;//[begin,end] begin和end是左闭右闭区间,因此有=号while (begin <= end){int mid = begin + ((end - begin) >> 1);if (a[mid] < x)begin = mid + 1;else if (a[mid] > x)end = mid - 1;elsereturn mid;}return -1;
}
二分查找的最好情况是O(1)
二分查找的最坏情况是找不到 时间复杂度为O(logN)
每查找一次 查找区间个数减少一半(除2)
N/2/2/2.../2 = 1
longlong Fac(size_t N)
{if (1 == N)return 1;return Fac(N - 1) * N;
}
时间复杂度为O(N)
longlong Fib(size_t N)
{if (N < 3)return 1;return Fib(N - 1) + Fib(N - 2);
}
时间复杂度为O(2^N)
longlong Fib(size_t N)
{if (N < 3)return 1;longlong f1 = 1, f2 = 1, f3;for (size_t i = 3; i <= N; ++i){f3 = f2 + f1;f1 = f2;f2 = f3;}return f3;
}
时间复杂度为O(N)
3.空间复杂度
空间复杂度也是一个数学表达式,是对一个算法在运行过程中额外占用存储空间大小的量度.
空间复杂度不是程序占用了多少字节的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数.
空间复杂度计算规则基本跟时间复杂度类似,也使用大O的渐进表示法.
注意:函数运行时所需要的栈空间(存储参数,局部变量,一些寄存器信息等)在编译期间已经确定好了,因此空间复杂度主要通过函数在运行时侯显示申请的额外空间来确定.
1G大约10亿字节 1G = 1024*1024*1024
1M大约100万字节 1M = 1024*1024
计算BubbleSort的空间复杂度
void BubbleSort(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;}
}
空间复杂度为O(1)
计算Fac的空间复杂度
longlong Fac(size_t N)
{if (N == 0)return 1;return Fac(N - 1) * N;
}
空间复杂度为O(N)
每个函数栈帧是常数个 有N+1个Fac栈帧
计算Fib的空间复杂度
longlong Fib(size_t N)
{if (N < 3)return 1;return Fib(N - 1) + Fib(N - 2);
}
空间复杂度为O(N)
4.常见时间复杂度以及复杂度OJ练习
一般算法常见的复杂度如下:
| 5201314 | O(1) | 常数阶 |
| 3n+4 | O(n) | 线性阶 |
| 3n^2+4n+5 | O(n^2) | 平方阶 |
| 3log(2)n+4 | O(logn) | 对数阶 |
| 2n+3nlog(2)n+14 | O(n*logn) | nlogn阶 |
| n^3+2n^2+4n+6 | O(n^3) | 立方阶 |
| 2^n | O(2^n) | 指数阶 |

复杂度的OJ练习:
消失的数字OJ链接:https://leetcode-cn.com/problems/missing-number-lcci/
int missingNumber(int* nums, int numSize)
{int x = 0;for (int i = 0; i < numSize; ++i){x ^= nums[i];}for (int j = 0; i < numSize + 1; ++j){x ^= j;}return x;
}
void reverse(int* a, int begin, int end)
{while (begin < end){int tmp = a[begin];a[begin] = a[end];a[end] = tmp;++begin;--end;}
}
void rotate(int* num, int numSize, int k)
{if (k > numSize)k %= numSize;reverse(nums, 0, numsSize - k - 1);reverse(nums, numSize - k, numsSize - 1);reverse(nums, 0, numsSize - 1);
}
相关文章:
【数据结构】复杂度讲解
目录 时间复杂度与空间复杂度:: 1.算法效率 2.时间复杂度 3.空间复杂度 4.常见时间复杂度以及复杂度OJ练习 时间复杂度与空间复杂度:: 什么是数据结构? 数据结构中是计算机存储,组织数据的方式,指相互之间存在一种或多种特定关…...
JAVA-线程池技术
目录 概念 什么是线程? 什么是线程池? 线程池出现背景 线程池原理图 JAVA提供线程池 线程池参数 如果本篇博客对您有一定的帮助,大家记得留言点赞收藏哦。 概念 什么是线程? 是操作系统能够进行运算调度的最小单位。&am…...
【C++】从0到1入门C++编程学习笔记 - 提高编程篇:STL常用算法(算术生成算法)
文章目录一、accumulate二、fill学习目标: 掌握常用的算术生成算法 注意: 算术生成算法属于小型算法,使用时包含的头文件为 #include <numeric> 算法简介: accumulate // 计算容器元素累计总和 fill // 向容器中添加元…...
【C++】static成员
💙作者:阿润菜菜 📖专栏:C 目录 概念 特性 出个题 概念 声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量; 用static修饰的成员函数,称之为静态…...
Python Scrapy 爬虫简单教程
1. Scrapy install 准备知识 pip 包管理Python 安装XpathCssWindows安装 Scrapy $>- pip install scrapy Linux安装 Scrapy $>- apt-get install python-scrapy 2. Scrapy 项目创建 在开始爬取之前,必须创建一个新的Scrapy项目。进入自定义的项目目录中&am…...
【DOCKER】容器概念基础
文章目录1.容器1.概念2.特点3.与虚拟机的对比2.docker1.概念2.命名空间3.核心概念3.命令1.镜像命令2.仓库命令1.容器 1.概念 1.不同的运行环境,底层架构是不同的,这就会导致测试环境运行好好的应用,到了生产环境就会出现bug(就像…...
第九层(16):STL终章——常用集合算法
文章目录前情回顾常用集合算法set_intersectionset_unionset_difference最后一座石碑倒下,爬塔结束一点废话🎉welcome🎉 ✒️博主介绍:一名大一的智能制造专业学生,在学习C/C的路上会越走越远,后面不定期更…...
一起学习用Verilog在FPGA上实现CNN----(六)SoftMax层设计
1 SoftMax层设计 1.1 softmax SoftMax函数的作用是输入归一化,计算各种类的概率,即计算0-9数字的概率,SoftMax层的原理图如图所示,输入和输出均为32位宽的10个分类,即32x10320 本项目softmax实现逻辑为: …...
pixhawk2.4.8-APM固件-MP地面站配置过程记录
目录一、硬件准备二、APM固件、MP地面站下载三、地面站配置1 刷固件2 机架选择3 加速度计校准4 指南针校准5 遥控器校准6 飞行模式7 紧急断电&无头模式8 基础参数设置9 电流计校准10 电调校准11 起飞前检查(每一项都非常重要)12 飞行经验四、遇到的问…...
【unity细节】关于资源商店(Package Maneger)无法下载资源问题的解决
👨💻个人主页:元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 收录于专栏:unity细节和bug ⭐关于资源商店为何下载不了的问题⭐ 文章目录⭐关于资源商店为何下载不了的问题…...
[Arxiv 2022] A Novel Plug-in Module for Fine-Grained Visual Classification
Contents MethodPlug-in ModuleLoss functionExperimentsReferencesMethod Plug-in Module Backbone:为了帮助模型抽取出不同尺度的特征,作者在 backbone 里加入了 FPNWeakly Supervised Selector:假设 backbone 的 i i...
RocketMQ Broker消息处理流程及部分源码解析
🍊 Java学习:Java从入门到精通总结 🍊 深入浅出RocketMQ设计思想:深入浅出RocketMQ设计思想 🍊 绝对不一样的职场干货:大厂最佳实践经验指南 📆 最近更新:2023年2月10日 &#x…...
Java面试题:Java集合框架
文章目录一、Java集合框架二、Java集合特性三、各集合类的使用ArrayListLinkedListHashSetHashSet源码解析对源码进行总结HashSet可同步HashSet的使用HashMap四、Iterator迭代器五、遍历集合元素的若干方式参考文章:Hash详解参考文章:深入浅出学Java——…...
时间之间的比较与计算相差年、月、日、小时、分钟、毫秒、纳秒以及判断闰年--LocalDateTime
如何把String/Date转成LocalDateTime参考String、Date与LocalDate、LocalTime、LocalDateTime之间互转 String、Date、LocalDateTime、Calendar与时间戳之间互相转化参考String、Date、LocalDateTime、Calendar与时间戳之间互相转化 比较方法介绍 isBefore(ChronoLocalDateT…...
PyTorch学习笔记:nn.L1Loss——L1损失
PyTorch学习笔记:nn.L1Loss——L1损失 torch.nn.L1Loss(size_averageNone, reduceNone, reductionmean)功能:创建一个绝对值误差损失函数,即L1损失: l(x,y)L{l1,…,lN}T,ln∣xn−yn∣l(x,y)L\{l_1,\dots,l_N\}^T,l_n|x_n-y_n| l(…...
Java程序设计-ssm企业财务管理系统设计与实现
摘要系统设计系统实现开发环境:摘要 对于企业集来说,财务管理的地位很重要。随着计算机和网络在企业中的广泛应用,企业发展速度在不断加快,在这种市场竞争冲击下企业财务管理系统必须优先发展,这样才能保证在竞争中处于优势地位。…...
疑难杂症篇(二十一)--Ubuntu18.04安装usb-cam过程出现的问题
对Ubuntu18.04{\rm Ubuntu 18.04}Ubuntu18.04环境下的ROS{\rm ROS}ROS的melodic{\rm melodic}melodic版本安装usb−cam{\rm usb-cam}usb−cam过程出现的两个常见问题提出解决方案。 1.问题1:usb-cam功能包编译时出现"未定义的引用"的问题 问题描述&#…...
npm-npm i XX --save 和--save-dev
之前使用npm i XX --save 和--save-dev 没太在意,就想记录一下,查到一篇比较全的(链接:NPM install -save 和 -save-dev 傻傻分不清),直接看好了,哈哈~ # 安装模块到项目目录下 npm install moduleName # -g 的意思是…...
可重构或可调谐微波滤波器技术
电子可重构,或者说电调微波滤波器由于其在改善现在及未来微波系统容量中不断提高的重要性而正吸引着人们越来越多的关注来对其进行研究和开发。例如,崭露头脚的超宽带(UWB)技术要求使用很宽的无线电频谱。然而,作为资源…...
医院智能化解决方案-门(急)诊、医技、智能化项目解决方案
【版权声明】本资料来源网络,知识分享,仅供个人学习,请勿商用。【侵删致歉】如有侵权请联系小编,将在收到信息后第一时间删除!完整资料领取见文末,部分资料内容:篇幅有限,无法完全展…...
YOLOv11目标检测与伏羲气象模型的融合应用:灾害天气图像识别预警
YOLOv11目标检测与伏羲气象模型的融合应用:灾害天气图像识别预警 最近几年,极端天气好像越来越频繁了。有时候,一场突如其来的暴雨或浓雾,就能让整个城市的交通陷入瘫痪,甚至带来不小的经济损失。传统的天气预报&…...
联想M920x黑苹果终极指南:从零构建完美macOS系统
联想M920x黑苹果终极指南:从零构建完美macOS系统 【免费下载链接】M920x-Hackintosh-EFI Hackintosh Opencore EFIs for M920x 项目地址: https://gitcode.com/gh_mirrors/m9/M920x-Hackintosh-EFI 你是否想让联想M920x这款紧凑型主机运行macOS系统ÿ…...
微信支付回调通知收不到的5个隐藏坑(附.NET Core实战解决方案)
微信支付回调通知失效的深度排查与.NET Core实战指南 当支付流程顺利完成但回调通知却神秘消失时,这种"薛定谔式的支付成功"往往让开发者陷入调试泥潭。本文将揭示五个容易被忽视的技术暗礁,并提供可直接集成到生产环境的.NET Core解决方案。 …...
PingFangSC 字体技术深度解析:现代Web字体架构实践指南
PingFangSC 字体技术深度解析:现代Web字体架构实践指南 【免费下载链接】PingFangSC PingFangSC字体包文件、苹果平方字体文件,包含ttf和woff2格式 项目地址: https://gitcode.com/gh_mirrors/pi/PingFangSC PingFangSC(苹方-简&#…...
如何高效配置Unity插件框架:BepInEx完整实战指南
如何高效配置Unity插件框架:BepInEx完整实战指南 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx BepInEx是一款专为Unity游戏设计的插件框架和补丁工具,能够…...
DbGate数据库管理工具:Docker一键部署与跨平台远程访问实战
1. 为什么选择DbGateDocker组合 第一次接触DbGate是在一个需要同时管理MySQL和MongoDB的项目中。当时团队里有人用Navicat,有人用DBeaver,数据库类型切换时总要重新适应界面。直到发现这个支持多数据库的开源工具,才真正体会到什么叫"一…...
AI结对编程:借助快马平台智能生成qclaw官网的AI功能模块
最近在开发qclaw官网时,尝试用AI辅助完成了一个合同条款分析功能,整个过程比想象中顺畅很多。这个功能的核心是让用户输入合同文本后,自动评估风险等级并给出提示。下面分享下具体实现思路和与AI协作的实践经验。 功能设计要点 首先明确这个…...
移动端ECharts实战:如何隐藏原生滚动条实现内容区域左右滑动(附完整代码)
移动端ECharts进阶:原生滚动条隐藏与手势滑动优化全解析 在移动端数据可视化项目中,ECharts的默认滚动条交互常常成为用户体验的"阿喀琉斯之踵"。当用户手指在狭小的滚动条上艰难拖动时,那种顿挫感和操作失败率会让精心设计的数据图…...
ae新手福音,用快马平台ai生成带注释的片段视频代码轻松入门
作为一个刚接触AE的新手,第一次打开软件时确实被复杂的界面吓到了。各种面板、时间轴、效果控件看得眼花缭乱,更别说要自己写表达式了。直到发现了InsCode(快马)平台,用自然语言描述就能生成带详细注释的AE项目代码,简直是新手的救…...
PlayCover 2.0重构Mac游戏体验:社交与云服务双引擎驱动革新
PlayCover 2.0重构Mac游戏体验:社交与云服务双引擎驱动革新 【免费下载链接】PlayCover Community fork of PlayCover 项目地址: https://gitcode.com/gh_mirrors/pl/PlayCover 在Mac平台运行iOS游戏长期面临两大痛点:缺乏社交连接与跨设备数据同…...
