数据结构第一课-----------数据结构的介绍
作者前言
🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂
🎂 作者介绍: 🎂🎂
🎂 🎉🎉🎉🎉🎉🎉🎉 🎂
🎂作者id:老秦包你会, 🎂
简单介绍:🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂
喜欢学习C语言和python等编程语言,是一位爱分享的博主,有兴趣的小可爱可以来互讨 🎂🎂🎂🎂🎂🎂🎂🎂
🎂个人主页::小小页面🎂
🎂gitee页面:秦大大🎂
🎂🎂🎂🎂🎂🎂🎂🎂
🎂 一个爱分享的小博主 欢迎小可爱们前来借鉴🎂
数据结构的初识
- **作者前言**
- 介绍
- 算法的时间复杂度和空间复杂度
- 算法效率
- 时间复杂度
- 大O渐进表示法
- 时间复杂度练习
- 空间复杂度
- 总结
介绍
数据结构:是计算机存储、组织数据的方式,指的是相互之间存在一种或者多种特定关系的数据元素的集合
如果学习过数据库的大佬就会知道,数据库主要是在硬盘上操作的管理数据,一般归结为增删改查,里面的精髓全部容纳在里面,而数据结构是在内存上管理数据的,
内存的读取速度快,价格高,带电存储,一旦掉电就会数据丢失,而硬盘的读取和存储速度就很慢,价格低 ,不带电存储,掉电不会数据丢失。
算法是定义良好的计算过程,他取一个或者一组的值输入,并产生出一个或者一组值作为输出,简单的说就是输入数据到输出数据之间的过程就是算法
算法的时间复杂度和空间复杂度
算法效率
1.代码简洁不一定效率高
#include<stdio.h>
int Fib(int a)
{if (a < 3){return 1;}else{return Fib(a - 1) + Fib(a - 2);}
}
int main()
{printf("%d", Fib(2));return 0;
这道题主要是求斐波那契数,使用了递归,代码虽然简便,但是计算过程却不简便,
衡量一个算法的好坏主要从两个维度来衡量。一个是时间复杂度,一个是空间复杂度,
时间复杂度主要是用来衡量一个算法的时间,时间越短,空间复杂度就越好。
空间复杂度是用来衡量一个算法在计算过程中空间的使用情况,可以理解,这个算法在使用过程中创建了多少个变量、数组、结构,浪费了多少内存,
时间复杂度
时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间,一个算法执行所消耗的时间,一个算法所花费的时间和其中语句的执行次数成正比,算法中的基本操作的执行次数就为算法的时间复杂度
注意这个函数不是C语言里面的函数,而是我们的数学函数,例如
aX^2 + bX+ c ; 这样的表达式
我们来练习一下
void Func1(int N)
{
int count = 0;for (int i = 0; i < N ; ++ i)
{for (int j = 0; j < N ; ++ j){++count;}
}for (int k = 0; k < 2 * N ; ++ k)
{++count;
}
int M = 10;
while (M--)
{++count;
}
我们可以利用我们学习的C语言常识来理解一下,第一个for循环执行了NN次
在外层的for首先每循环一次,里面for就会循环N次,外层有N次,总共就会循环NN次,第二个for循环了2N次
第三个while循环了10次
int count = 0;也执行了一次
所以全部就执行了 F(N) = NN+ 2N+ 11,随着N的增大主要影响这个表达式的结果时NN,所以我们计算时间复杂度就要取这个影响最大的项,那我们就可以使用一种方法大O渐进表示法
O(N^2)
大O渐进表示法
主要是进行估算的
大O符号(Big O notation):是用于描述函数渐进行为的数学符号。
推导大O阶方法:
1、用常数1取代运行时间中的所有加法常数。例如O(1),只要运行的次数是常数就用这个来表示
2、在修改后的运行次数函数中,只保留最高阶项。
3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。
时间复杂度练习
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);
}
这里我们可以的数学表达是就是 F(N) = 2*N + 10, 大O渐进表示就是O(N)
// 计算Func3的时间复杂度?
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);
}
这道题的时间复杂度的数学表达式是M+ N+ 1,大O渐进表示O(M + N),
这里如果是M大于N就是O(M),如果是M小于 N就是O(N),如果M=N就是O(M)或者O(N)
void Func4(int N)
{int count = 0;for (int k = 0; k < 100; ++ k){++count;}printf("%d\n", count);
}
这里的时间复杂度是一个常量,是常量,大O渐进表示就是O(1).
下面我引入一个函数
#include<stdio.h>
#include<string.h>
int main()
{char *p = strchr("dfksdfsfkl", 's');printf("%p", p);return 0;
}
这个函数的作用是在一个字符串中找字符,找到就返回第一次出现的地址,否则返回NULL
str是要进行查找的字符串。
charcter是要查找的字符,它以整数形式传递,通常使用字符的ASCII码。
假设我们要找一个字符,这个字符可能存在第一个,可能中间,或者末尾,
这种方法叫预期管理法
有些算法的时间复杂度存在最好、平均和最坏情况:
最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数(下界)
例如:在一个长度为N数组中搜索一个数据x
最好情况:1次找到
最坏情况:N次找到
平均情况:N/2次找到
在实际中一般情况关注的是算法的最坏运行情况,所以数组中搜索数据时间复杂度为O(N)
// 计算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;}
}
这里的我们还要区分一下,两层for不一定是O(N^2),还有可能是O(N),这里的计算主要是次数
(n - 1) + (n - 2)+…+1 +0利用等差数列公式可以求出是n(n -1)/2
时间复杂度主要还是根据代码的思路去进行判断,而不是根据代码,前面根据代码计算时间复杂度是因为前面的代码思路简单
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(log N),为啥是O(log N),我们可以想象一下,当我们通过二分查找当找到最后一个的时候,我们可以反过来想,每次寻找元素个数都减半,那我们通过最后一个元素来反推出元素总数
假设最后找到最后一个元素, 次数设为x ,总数是N , 122*…2 = N我们可以发现,当我们每找一次就会除2.那有找了x次就会有x个2,也就是2^x = N,时间复杂度算的是次数,x = log N(默认以2为底)
// 计算阶乘递归Fac的时间复杂度?
long long Fac(size_t N)
{if(0 == N)return 1;return Fac(N-1)*N;
}
这里的时间复杂度为O(N), 当参数值为N时 函数调用N次,每次为1,所以时间复杂度就是O(N),时间复杂度算的是次数
// 计算斐波那契递归Fib的时间复杂度?
long long Fib(size_t N)
{if(N < 3)return 1;return Fib(N-1) + Fib(N-2);
}
我们可以看左边,就像一个直角三角型一样 , 总共有N层 ,每一层是2的幂
第一层 2^0,第二层2 ^1 …,
最终的结果 2^0 + 2^1 +2 ^2 +2 ^3 +…+ 2^(N -2),等比数列 :2^(N- 1) - 1
所以最终是O(2 ^N),这种思路我们可以学习,但是实际价值却很低
我们可以使用循环来减少时间复杂度
#include<stdio.h>
#include<string.h>
int main()
{int n1 = 1;int n2 = 1;int n3 = 1;int num = 0;scanf("%d", &num);int i = 0;for (i = 0; i < (num - 2) && num >2; i++){n3 = n1 + n2;n1 = n2;n2 = n3;}printf("%d", n3);return 0;
}
空间复杂度
空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度 。
空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。
空间复杂度计算规则基本跟实践复杂度类似,也使用大O渐进表示法。
注意:函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,因此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定。
// 计算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;}
}
这里的变量创建了3个空间复杂度s
在计算空间复杂度时,形参通常不会被考虑在内。空间复杂度主要关注的是算法执行过程中所使用的额外空间,而形参通常是在函数调用时传递的参数,不会占用额外空间。因此,在计算空间复杂度时,通常只考虑算法中使用的变量、数据结构和临时空间等。
// 计算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;fibArray[1] = 1;for (int i = 2; i <= n ; ++i){fibArray[i] = fibArray[i - 1] + fibArray [i - 2];}return fibArray;
}
这里主要是创建了n+1个空间进行存储,空间复杂度是O(n)
那下面我来推荐一道题
这道题我们可以通过创建额外的空间让时间复杂度降低, 数组中的元素充当额外数组的下标,遍历一遍额外数组找出不存在的,就可以解出来,空间复杂度是O(n).时间复杂度是O(n)
// 计算阶乘递归Fac的空间复杂度?
long long Fac(size_t N)
{if(N == 0)return 1;return Fac(N-1)*N;
}
这里主要是递归,函数里面调用函数
调用情况:
一共调用了N次,总共创建了N个空间,空间复杂度是O(N)
而我们计算斐波那契数的空间复杂度也是O(N)
因为递归的空间复杂度,也是空间的累计,但是不同的是空间是重复利用,为啥要这样说呢?
因为函数调用是一个个调用的,不是一下子调用全部函数
下面的代码可以演示
#include<stdio.h>
#include<string.h>
int fun(int N)
{int a = 0;printf("%p\n", &a);
}
int fun1(int N)
{int a = 0;printf("%p\n", &a);
}
int main()
{fun(1);fun1(1);return 0;
}
总结
时间复杂度和空间复杂度就介绍到这里了,感兴趣的小可爱可以私聊我
相关文章:

数据结构第一课-----------数据结构的介绍
作者前言 🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂 🎂 作者介绍: 🎂🎂 🎂 🎉🎉🎉…...
Python武器库开发-常用模块之OS模块(十一)
常用模块之OS模块(十一) Python中的 os 模块提供了非常丰富的方法用来处理文件和目录,可以执行一些操作系统的功能。常用的方法如下表所示: 序号方法描述1os.access(path, mode)检验权限模式2os.chdir(path)改变当前工作目录3os.chflags(path, flags)设…...

Vectrosity 插件使用
1 下载 https://download.csdn.net/download/moonlightpeng/88490704?spm1001.2014.3001.5503 2 使用,目前在2020.3.3上测试可以 导入时选5.6 再导入demo...
数据结构详细笔记——并查集
文章目录 逻辑结构存储结构并、查代码实现Union 操作的优化Find 操作的优化(压缩路径) 逻辑结构 集合:将各个元素划分为若干个互不相交的子集的集合 森林是m(m>0)棵互不相交的树的集合 存储结构 #define SIZE 13 int UFSets[SIZE]; …...

transformers-Generation with LLMs
https://huggingface.co/docs/transformers/main/en/llm_tutorialhttps://huggingface.co/docs/transformers/main/en/llm_tutorial停止条件是由模型决定的,模型应该能够学习何时输出一个序列结束(EOS)标记。如果不是这种情况,则在…...

maven之父子工程版本控制案例实战,及拓展groupId和artifactId的含义
<parent>标签 用于父子工程项目,什么是父子工程? 顾名思义,maven父子项目是一个有一个父项目,父项目下面又有很多子项目的maven工程,当然,子项目下面还可以添加子项目,从而形成一个树形…...

100量子比特启动实用化算力标准!玻色量子重磅发布相干光量子计算机
2023年5月16日,北京玻色量子科技有限公司(以下简称“玻色量子”)在北京正大中心成功召开了2023年首场新品发布会,重磅发布了自研100量子比特相干光量子计算机——“天工量子大脑”。 就在3个月前,因“天工量子大脑”在…...

JAVA基础(JAVA SE)学习笔记(十)多线程
前言 1. 学习视频: 尚硅谷Java零基础全套视频教程(宋红康2023版,java入门自学必备)_哔哩哔哩_bilibili 2023最新Java学习路线 - 哔哩哔哩 第三阶段:Java高级应用 9.异常处理 10.多线程 11.常用类和基础API 12.集合框架 13.泛型 14…...

ChatGPT参数只有200亿?扩散代码模型,意外泄露
微软的研究部门发布了一篇关于预训练扩散代码模型CodeFusion的论文。在展示代码生成任务的基线数据对比时,发现了一个有趣的事情,ChatGPT(gpt-3.5-turbo)的参数只有200亿。 要知道,gpt-3.5-turbo是OpenAI中应用最多、…...
VR虚拟仿真教学在建筑学课堂中的应用
1. 增强真实感:VR技术能创造出近乎真实的虚拟环境,使学生仿佛置身其中,增强他们的感官体验。 2. 打破空间限制:VR教学可以打破时间和空间的限制,学生可以在任何时间、任何地点进行学习,无需担心课堂位置的…...

竞赛 深度学习实现行人重识别 - python opencv yolo Reid
文章目录 0 前言1 课题背景2 效果展示3 行人检测4 行人重识别5 其他工具6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **基于深度学习的行人重识别算法研究与实现 ** 该项目较为新颖,适合作为竞赛课题方向,…...

当代都市的时尚先锋:气膜建筑的魅力
当代城市的崛起如一部快速奔腾的时光流。在这个光速发展的都市中,时间被看作珍贵的黄金,而效率被视为无价的生命。而在这个节奏日益加快的现代都市背后,一个独特的“神器”——气膜建筑,悄然崭露头角,成为城市发展的领…...

品牌加盟商做信息展示预约小程序的效果如何
很多行业都有中部或头部品牌,对实体品牌企业来说想要快速高效发展,除了多地直营店外还需要招募加盟商进而提升生意营收。 因此线上渠道变得尤为重要,除了网站外,小程序是连接多平台生态很好的工具,随时打开、直接触达…...

delphi 11.3 FastReport 多设备跨平台 打印之解决方法
以下能WINDOWS10 DELPHI 11.3 FastReport6.0上顺利通过 FastReport6.2对Multi-Device Application应用的支持不够友好,如下图;在palette FastReport6.0才出现几个制件。 非Multi-Device Application应用时是一大堆; 非Multi-Device Appl…...

配置vue 环境
一、安装Node.js及配置环境 环境变量配置 第一步:“此电脑”-右键-“属性”-“高级系统设置”-“高级”-“环境变量” 第二步(我的为:C:\Program Files\nodejs ),然后编辑path,新建,为…...

Visio文件编辑查看工具Visio Viewer for Mac
Visio Viewer mac版是一款Visio文件查看工具,可以使用本程序打开所有的visio文件数据,支持多种语言环境,可以对visio文件进行编辑、跳转参数等设置。 Visio Viewer for Mac可以打开和查看Visio文件(.vsd、.vdx和.vsdm文件&#x…...

现在软文发布平台都有哪些?如何在正规媒体发稿?
近年来,随着广告行业竞争愈加激烈,越来越多的企业开始注重软文宣传。软文推广平台是企业在网络上发布软文、传播信息和推广产品的重要工具。 媒介易软文平台介绍更好的品牌宣传和市场推广:软文推广发稿有哪些平台, 软文发稿好方法?软文不仅能…...

【卷积神经网络】YOLO 算法原理
在计算机视觉领域中,目标检测(Object Detection)是一个具有挑战性且重要的新兴研究方向。目标检测不仅要预测图片中是否包含待检测的目标,还需要在图片中指出它们的位置。2015 年,Joseph Redmon, Santosh Divvala 等人…...

云计算与ai人工智能对高防cdn的发展
高防CDN(Content Delivery Network)作为网络安全领域的一项关键技术,致力于保护在线内容免受各种网络攻击,包括分布式拒绝服务攻击(DDoS)等。然而,随着人工智能(AI)和大数…...

Web3时代:探索DAO的未来之路
Web3 的兴起不仅代表着技术进步,更是对人类协作、创新和价值塑造方式的一次重大思考。在 Web3 时代,社区不再仅仅是共同兴趣的聚集点,而变成了一个价值交流和创新的平台。 去中心化:超越技术的革命 去中心化不仅仅是 Web3 的技术…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...