数据结构开始——时间复杂度和空间复杂度知识点笔记总结
好了,经过了漫长的时间学习c语言语法知识,现在我们到了数据结构的学习。
首先,我们得思考一下
什么是数据结构?
数据结构(Data Structure)是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。
算法又是什么?
定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为输出。简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果
算法讲究效率
如何衡量一个算法的好坏
如,斐波那契数列(虽然代码简单,但是它的效率高吗?)
long long Fib(int n)
{
if(n < 3)
{return 1;
}return Fib(n-1) + Fib(n-2);
}

是先(黑色)一步一步进去下去,算到Fib(1)时,再一步一步返回上去(红色)
这得花费非常多的时间,效率并不高。
因此,要衡量一个算法的好坏,一般是从时间和空间两个维度来衡量的即时间复杂度,空间复杂度
时间复杂度和空间复杂度
时间复杂度和空间复杂度的区别
作用:时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间(由于目前的空间都很大,基本不用担心空间的)
时间复杂度
时间复杂度:算法的时间复杂度是一个函数
一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度也就是:找到某条基本语句与问题规模N之间的数学表达式,就是算出了该算法的时间复杂度。
请计算一下Func1中++count语句总共执行了多少次?
void Func1(int N)
{
int count = 0;
for (int i = 0; i < N ; ++ i)
{
for (int j = 0; j < N ; ++ j)
{ 这里是N^2
++count;
}
}
for (int k = 0; k < 2 * N ; ++ k)
{
++count; 这里是2*N
}
int M = 10;
while (M--)
{ 这里是10次
++count;
}
经过计算我们可以得出:是F(N)=N^2+2*N+10
其实,对于求复杂度,我们一般使用大O的渐进表示法,,现在来介绍下:
大O的渐进表示法
1.大O符号:是用于描述函数渐进行为的数学符号
2.规则方法:
1)用常数1取代运行时间中的所有加法常数。
2)、在修改后的运行次数函数中,只保留最高阶项。
3)、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。
最后得到的结果就是大O阶
eg:N(10000000000000)这应该写成什么呢?
答案:仍然是O(1).
有人会问为啥它这个数那么大了,还是用O(1)表示呢?
现在我们来用形象的例子来解释下:
假如那里有座泰山,我们要铲平,
不同视角:会不同
我们人的视角觉得它非常大,
但是放到太阳系里面,就显得非常小了。同样,对于编程也是一样的道理。
通过上面我们会发现大O的渐进表示法去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数
另外有些算法的时间复杂度存在最好、平均和最坏情况:
最坏情况:任意输入规模的最大运行次数(上界)平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数(下界)例如:在一个长度为N数组中搜索一个数据x
最好情况:1次找到最坏情况:N次找到平均情况:N/2次找到
所以,我们实际中一般关注的是最坏的情况。
原因:同样是以一个形象的例子来解释
约会的预期管理
情人节约会可能到时的时间
最好:17:00
平均:18:00
最坏:19:00
那么因为只有30%的机会准时到
所以是不是选择说19:00时最好,把预期拉到最低。
常见时间复杂度计算举例
void Func2(int N)
{
int count = 0;
for (int k = 0; k < 2 * N ; ++ k)
{ 这里是2*N次
++count;
}
int M = 10;
while (M--) 这里是10次
{
++count;
}
printf("%d\n", count);
}
所以,函数是不是就是:F(N)=2*N+10
根据大O法:得时间复杂度就是O(N)
例子2:
// 计算Func3的时间复杂度?
void Func3(int N, int M)
{
int count = 0;
for (int k = 0; k < M; ++ k)
{
++count; 这里是M次
}
for (int k = 0; k < N ; ++ k)
{ 这里是N次
++count;
}
printf("%d\n", count);
}
函数式:F(N)=M+N
注意:这里的M,N都是未知数,并不是具体数
所以根据大O法:时间复杂度O(M+N)
例子3:
// 计算Func4的时间复杂度?
void Func4(int N)
{
int count = 0;
for (int k = 0; k < 100; ++ k)
{ 这里是100次
++count;
}
printf("%d\n", count);
}
函数式:F(N)=100
根据大O法:由于它是常数嘛,所以用1代替
所以时间复杂度:O(1).
例子4:
const char * strchr ( const char * str, int character );
对于指针,如果没有具体说,一般默认都是O(N)
例子5:
void BubbleSort(int* a, int n)
{
assert(a);
for (size_t end = n; end > 0; --end){ 一般没说的话,默认N次int exchange = 0;for (size_t i = 1; i < end; ++i) 因为两个for循环,所以是N^2次{if (a[i-1] > a[i]){Swap(&a[i-1], &a[i]);exchange = 1;}}if (exchange == 0) 因为这里有了判断,它可以改变最好的情况break; 如果没有这句,} 最好也是O(N^2)因为它无法知道它已经排序了 }
排序
最好(已经排序好大小):O(1) X有人说是看一眼就知道它的大小排序了,但是你一亿的时候呢,你并不知道其他数字2与这个的大小?
你是不是也是要一个一个对比下去呢?
所以 时间复杂度: O(N) √最坏:O(N^2)
其实这里不敢数循环,因为以后会学更复杂的
N-1 N-2 N-3....3 2 1 等差数列 算出O(N^2)
例子5:我们之前写过的二分查找
int BinarySearch(int* a, int n, int x)
{assert(a);int begin = 0;int end = n-1;while (begin < end){int mid = begin + ((end-begin)>>1);if (a[mid] < x)begin = mid+1;else if (a[mid] > x)end = mid;elsereturn mid;
}return -1;
}
四 第三次 第二次 第一次
我们可以发现,这是不是一次查找,我们就可以筛选掉一半。
最坏情况:区间缩放到一个值时,要么找到,要么找不到
假设N是数组个数,x是最坏查找次数
N/2/2/2/2.../2=1
折半查找多少次就除多少个2
假设是x次2^x=N
x=log N
这里我们先来说明一下:

接着,我们来看一下二分查找的显著优势:
对比:
N 1000 100W 10亿 2^10=1024
O(N) 1000 100W 10亿 2^20=1024*1024
O(log N) 10 20 30 2^30=1024*1024*1024我们可以看到这二分查找极大改变它的时间效率。
但是一个很不友好的一点是,它仅仅局限于排序好的数,所以我们以后也不太实用
例子6:
计算阶乘递归Fac的时间复杂度?
long long Fac(size_t N)
{
if(0 == N)
return 1;
return Fac(N-1)*N;
}

这是不是相当于有N+1次,O(N+1)
根据大O法:时间复杂度:O(N)
Fac(N)
Fac(N-1)
Fac(N-2)
....
Fac(1)
Fac(0)
例子七:
// 计算斐波那契递归Fib的时间复杂度?
long long Fib(size_t N)
{
if(N < 3)
return 1;
return Fib(N-1) + Fib(N-2);
}

等比数列 -缺失(常数)
时间:O(2^N)
空间:O(N)对此,我们可以得出来:
时间一去不复返,不可重复利用
空间用了以后要归还,可以重复利用。
空间复杂度
1.空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度
2.空间复杂度算的是变量的个数(而不是程序占用了多少bytes的空间,因为这个也没太大意义)
注意:函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,因此空间复杂度主要通过函数在运行时候显示申请的额外空间来确定。
3.空间复杂度的使用规则也是:大O法
空间复杂度举例:
例子1:
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;}
}
我们上面说了空间复杂度算的是变量的个数
我们看到了上面用了三个变量:end,exchange,i。 -->O(3)
根据大O法:O(1).
例子2:绝大多数空间复杂度都是O(1)或O(N)
计算Fibonacci的空间复杂度?返回斐波那契数列的前n项
long long* Fibonacci(size_t n)
{if(n==0)return NULL; long long * fibArray = (long long *)malloc((n+1) * sizeof(long long));fibArray[0] = 0; 为什么要多加1,因为数组从0开始,fibArray[1] = 1; for (int i = 2; i <= n ; ++i){fibArray[i] = fibArray[i - 1] + fibArray [i - 2];}return fibArray;
}
上面创建了n+1个空间
所以根据大O法:O(N)
例子3:
// 计算阶乘递归Fac的空间复杂度?
long long Fac(size_t N)
{
if(N == 0)
return 1;
return Fac(N-1)*N;
}
值得注意的是
递归调用了N次,开辟了N个栈帧,每个栈帧使用了常数个空间
函数在栈的开辟函数栈帧时是单独开辟的。调用本身时,会再2开辟一块空间作为新的函数栈帧,但是在此外并没有创建额外的变量,所以会认为创建的每一块栈帧空间复杂度变量是常数个。
举个形象例子:
空间销毁是把那个使用权还给操作系统了,并不是说这块空间就没了
内存的申请,就相当于 住酒店一样,当这房间不用了,这不是说把它炸所以参数从N到0,共递归了N+1次,
根据大O法:O(N)
例子6:
同样,斐波那契数列也是一样。
long long Fib(size_t N)
{
if(N < 3)
return 1;
return Fib(N-1) + Fib(N-2);
}
空间销毁是把那个使用权还给操作系统了,我们上面说过空间是可以重复使用的,
调用某个函数结束后,再次调用此函数,所用的空间与上一次的函数空间是同一个。
所以,同样是递归了N-1次
由大O法:O(N)。
大O的常见的变化表

祝福语:
最后的最后,希望我们都能战胜困难,一步一步地坚持下去,为以后拿到好offer!
相关文章:
数据结构开始——时间复杂度和空间复杂度知识点笔记总结
好了,经过了漫长的时间学习c语言语法知识,现在我们到了数据结构的学习。 首先,我们得思考一下 什么是数据结构? 数据结构(Data Structure)是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素…...
路由策略与策略路由
路由策略 常用有Router-Policy,Filter-Policy等 控制路由是否可达,通过修改路由条目相关参数影响流量的转发 基于控制平面,会影响路由表表项,但只能基于目地址进行策略判定,于路由协议相结合使用 Router-Policy …...
pytorch_fid 安装笔记
目录 torch安装: pytorch_fid安装 torch安装: pip install torch2.5.0 --index-url https://download.pytorch.org/whl/cu121 pytorch_fid安装 pip install pytorch_fid 安装后,torch也会自动安装,导致torch引用报错。...
Qt绘制仪表————附带详细说明和代码示例
文章目录 1 效果2 原理3 编码实践3.1 创建仪表属性类3.2 设置类属性3.3 绘制图案3.3.1 设置反走样3.3.2 绘制背景3.3.3 重新定义坐标原点3.3.4 绘制圆环3.3.5 绘制刻度线3.3.6 绘制刻度线上的描述值3.3.7 绘制指针3.3.8 绘制指针数值和单位3.3.9 控制指针变化 扩展福利参考 1 效…...
百度地图JavaScript API核心功能指引
百度地图JavaScript API是一套由JavaScript语言编写的应用程序接口,它能够帮助您在网站中构建功能丰富、交互性强的地图应用,包含了构建地图基本功能的各种接口,提供了诸如本地搜索、路线规划等数据服务。百度地图JavaScript API支持HTTP和HT…...
mp4影像和m4a音频无损合成视频方法
第一步:复制高清视频地址 url 第二步:打开网址粘贴复制的视频url视频下载 第三步:下载-影像.mp4和-音频.m4a 第四步:合并视频; 使用ffmpeg进行无损合成(如果没有安装ffmpeg请自行下载安装下载 FFmpeg (p2hp.com)&…...
Ubuntu下将Julia嵌入Jupyter内核
一.安装 Julia 如果 Julia 尚未安装: 打开终端,下载最新的 Julia 安装包: wget https://julialang-s3.julialang.org/bin/linux/x64/1.9/julia-1.9.3-linux-x86_64.tar.gz 解压并移动到 /opt: tar -xvzf julia-1.9.3-linux-x86_…...
openGauss开源数据库实战二十五
文章目录 任务二十五 openGauss 数据库的物理备份与恢复任务目标实施步骤一、为进行物理备份做准备1.确保数据库工作在归档模式2.创建保存数据库物理备份的目录3.创建保存归档日志备份的目录 二、进行openGauss数据库的物理备份1.备份数据库2.切换WAL3.备份归档日志 三、openGa…...
[C/C++] List相关操作
List相关操作 1 链表二分 目标: (1)对于偶数节点,正好对半分; (2)对于奇数节点,前 后 1 (3)断开链表,方便后期合并 // 使用快慢指针完成中点…...
继电器控制与C++编程:实现安全开关控制的技术分享
在现代生活中,继电器作为一种重要的电气控制元件,在电气设备的安全控制中起到了至关重要的作用。通过低电流控制高电流,继电器能够有效地隔离控制电路与被控设备,从而保障使用者的安全。本项目将介绍如何通过树莓派Pico与继电器模块结合,使用C++编程实现继电器的控制。 一…...
题解 - 找子序列(2024.12上海月赛丙组T4)
题目描述 Dave 有一个长度为 n 的非负整数序列 a1-n, 和一个非负整数 m 。 他希望知道是否有一个 a 的非空子序列,使得子序列中所有元素的按位与(bitwise AND)结果为 m。 换言之,他想知道是否存在一个下标序列 i1-k(k ≥ 1),满足 1 ≤ i1 < i2 < …...
在centos 7.9上面安装mingw交叉编译工具
1.说明 为了在centos上面编译windows的程序,需要安装mingw工具,mingw工具是可以编译windows程序的一些工具链,使用方式和linux一致 2.下载脚本 使用脚本方式编译,github的脚本位置:https://github.com/Zeranoe/ming…...
ubuntu wine mobaxterm找不到串口和解决方案
安装好 打开MobaXterm时发现,没有可供选择的串口 我们再检查wine设备映射 ls -la ~/.wine/dosdevices/ 串口是存在的,我们再来一番神操作,并没有回滚操作,不知是否是必要修改 打开 注册表,在HKEY_LOCAL_MACHINE中的…...
如何编译安装系统settings设置应用(5.0.0-Release)
本文介绍如何在OpenHarmony 5.0.0 r版本中修改系统设置应用,并且编译安装到开发板上 开发环境 1.dayu200开发板 2.OpenHarmony 5.0.0r 固件 3.API12 full sdk (如果安装full sdk过程中出现报错hvigor ERROR: Cannot find module typescript,请参考 h…...
<项目代码>YOLOv8 车牌识别<目标检测>
项目代码下载链接 <项目代码>YOLOv8 车牌识别<目标检测>https://download.csdn.net/download/qq_53332949/90121387YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题…...
协同办公软件新升级:细节优化,让办公更简单
细节决定成败,企业酷信协同办公系统通过贴近客户实际需求的一系列改进和创新,在技术架构、系统结构、管理理念和使用性能上,都达到了国内先进水平,同时具备独特的优势。让我们看看企业酷信是如何通过这些细节提升,为企…...
【原创学习笔记】西门子1200 PLC实现变频器控制
一、实现的功能及应用的场合 通过PLC的不同指令,发送指令控制电机的启停和速度大小 二、硬件配置 1、西门子1214 PLC 2.TIA V16 3.SINAMICS G120C 三、实现功能步骤 1.添加设备G120C PN-调整以太网地址 根据实际情况选择有无滤波器,电机参数…...
SQL server学习02-使用T-SQL创建数据库
目录 一, 使用T-SQL创建数据库 1,数据库的存储结构 2,创建数据库的语法结构 1)使用T-SQL创建学生成绩管理数据库 二,使用T-SQL修改数据库 1,修改数据库的语法结构 1)修改学生成绩管理数…...
2024153读书笔记|《春烂漫:新平摄影作品选》——跳绳酷似人生路,起落平常,进退平常,莫惧征途万里长
2024153读书笔记|《春烂漫:新平摄影作品选》——跳绳酷似人生路,起落平常,进退平常,莫惧征途万里长 《春烂漫:新平摄影作品选》作者新平,2019.12.25年读完的小书,当时就觉得挺不错,今…...
MySQL有哪些高可用方案?
大家好,我是锋哥。今天分享关于【MySQL有哪些高可用方案?】面试题。希望对大家有帮助; MySQL有哪些高可用方案? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MySQL 高可用方案旨在确保数据库系统的高可靠性、低宕机时间、以及在硬件故障…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

