当前位置: 首页 > news >正文

【数据结构】复杂度

🔥博客主页:小王又困了

📚系列专栏:数据结构

🌟人之为学,不日近则日退 

❤️感谢大家点赞👍收藏⭐评论✍️


目录

一、什么是数据结构

二、什么是算法

三、算法的效率

四、时间复杂度

4.1大O渐进表示法

4.2常见时间复杂度计算举例

4.3例题:消失的数字

五、空间复杂度 

5.1空间复杂度计算 

5.2例题:轮转数组


🗒️前言

在前面我们讲完了C语言的内容,从本期开始我们将进入数据结构的学习,本期介绍了数据结构的概念和算法分析的初步知识。

一、什么是数据结构

数据结构(Data Structure)是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合。

二、什么是算法

算法(Algorithm)是定义良好的计算过程,它取一个或一组的值为输入,并产生出一个或一组值作为输出。简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果

三、算法的效率

我们会通过复杂度去衡量一个算法的好坏。算法在编写成可执行程序后,运行时需要耗费时间资源和空间(内存)资源 。因此衡量一个算法的好坏,一般是从时间和空间两个维度来衡量的,即时间复杂度和空间复杂度。

时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间。在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在乎。但是经过计算机行业的迅速发展,计 算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。

四、时间复杂度

时间复杂度的概念

时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一 个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个 分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。

即:找到某条基本语句与问题规模N之间的数学表达式,就是算出了该算法的时间复杂度。

4.1大O渐进表示法

实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,所以这里我们使用大O的渐进表示法。 

大O符号:是用于描述函数渐进行为的数学符号。

推导大O阶方法:

1.用常数1取代运行时间中的所有加法常数。

2.在修改后的运行次数函数中,只保留最高阶项。

  3.如果最高阶项存的系数不为1,则去除这个项的系数。

另外有些算法的时间复杂度存在最好、平均和最坏情况:

  • 最坏情况:                                                                                                                                   任意输入规模的最大运行次数(上界)
  • 平均情况:                                                                                                                                 任意输入规模的期望运行次数
  • 最好情况:                                                                                                                               任意输入规模的最小运行次数(下界)

说明:在实际中一般情况关注的是算法的最坏运行情况。

4.2常见时间复杂度计算举例

🚩冒泡排序:

// 计算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(N)

        最好情况就是数组本身有序,虽然它有序,但是计算机最初并不知道它是有序的,仍需要遍历一遍数组才能知道它是有序的,所以就好情况就是O(N)。

📒最坏情况:O(N^2)

        最坏情况是数组完全逆序,则第一趟需要交换N − 1 次,第二趟需要交换N − 2次…直到最后一趟只交换一次,把所有的交换次数加起来就得到了冒泡排序最坏情况下的时间复杂度,其实也就是一个等差数列求和,所以最会情况下的时间复杂度是O(N^2)

 🚩二分查找

// 计算BinarySearch的时间复杂度?
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(1)。

📒最坏情况:O(log2N)
        二分查找每次可以排出一半的数据,就坏的情况就是排出到只剩下一个数据。当N/2/2/2/2……/2=1时,就找到了目标值。除去了几个2就是执行的次数,所以时间复杂度为O(log2N)。

O(N)和O(log2N)的对比:

N1000100W10亿
O(N)1000100W10亿
O(log2N)102030

由此我们看到O(log2N)相对O(N)在效率上有很大的提升,但二分查找有一个限制条件就是数组必须有序,所以在实际中二分查找应用并不多。

🚩递归阶乘

// 计算阶乘递归Fac的时间复杂度?
long long Fac(size_t N)
{if (0 == N)return 1;return Fac(N - 1) * N;
}

📒时间复杂度:O(N)

        Fac一共被递归调用了N+1次,且每次Fac中执行1次,总共执行N+1次,所以时间复杂度是O(N)。

🚩斐波那契数

// 计算斐波那契递归Fib的时间复杂度?
long long Fib(size_t N)
{if (N < 3)return 1;return Fib(N - 1) + Fib(N - 2);
}

 📒时间复杂度:O(2^N)

        斐波那契额数列,它的时间复杂度是等比数列求和,所以时间复杂度为O(2^N)。

4.3例题:消失的数字

💡思路一: 

        我们可以把0~N个数字全部加起来,减去数组中的元素,结果就是消失的数字。

时间复杂度为O(N)

int missingNumber(int* nums, int numsSize)
{int i=0;int ret=N*N/2;for(i=0;i<numsSize;i++){ret-=nums[i];}return ret;
}

💡思路二:

        我们可以使用异或,异或的条件是相同为0,相异为1。两个相同的数异或为0,0和任何数异或都为原数,所以我们将0~N与数组中的所有异或,得到的结果就是消失的数。

int missingNumber(int* nums, int numsSize)
{int m=0;int i=0;for(i=0;i<=numsSize;i++){m^=i;}for(i=0;i<numsSize;i++){m^=nums[i];}return m;
}

五、空间复杂度 

空间复杂度的概念:

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度 。 空间复杂度不是程序占用了多少bytes的空间,而算的是变量的个数。 空间复杂度计算规则也使用大O渐进表示法。

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

一般常见的空间复杂度都是O(1)或者O(N)(额外开辟数组)。

5.1空间复杂度计算 

🚩递归阶乘:

// 计算阶乘递归Fac的空间复杂度?
long long Fac(size_t N)
{if(N == 0)return 1;return Fac(N-1)*N;
}

📒空间复杂度:O(N)

        函数的每一次调用都会开辟一个栈帧,每个栈帧开常数个空间,开辟N+1个栈帧,空间复杂度就为O(N)。

 递归程序最大的问题就是深度太深,会有栈溢出的风险。

🚩 斐波那契数

long long Fib(size_t N)
{if(N < 3)return 1;return Fib(N-1) + Fib(N-2);
}

📒空间复杂度:O(N)

        空间是可以重复利用的,递归的调用是按一条线递归下去的,不会同时递归,当递归到最后一层返回时,创建的函数栈帧销毁,调用另一条仍可以使用这块空间,所以空间复杂度是O(N)。

5.2例题:轮转数组

 💡思路

  1. 逆置前n-k个
  2. 逆置后k个
  3. 整体逆置
void reverse(int* nums,int left,int right)
{int tmp=0;while(left<=j){tmp=nums[left];nums[left]=nums[right];nums[right]=tmp;left++;right--;         }
}void rotate(int* nums, int numsSize, int k)
{if(k==0){return nums;}reverse(nums,0,numsSize-1);reverse(nums,0,k%numsSize-1);reverse(nums,k%numsSize,numsSize-1);
}

本次的内容到这里就结束啦。希望大家阅读完可以有所收获,同时也感谢各位读者三连支持。文章有问题可以在评论区留言,博主一定认真认真修改,以后写出更好的文章。你们的支持就是博主最大的动力。

相关文章:

【数据结构】复杂度

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;数据结构 &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、什么是数据结构 二、什么是算法 三、算法的效率 四、时间复杂度 4.…...

【读点论文】PP-YOLOE: An evolved version of YOLO,面向友好部署的模型设计,为项目后续产业落地提供了更加有效的参考

PP-YOLOE: An evolved version of YOLO Abstract 在本报告中&#xff0c;我们介绍了PP-YOLOE&#xff0c;一种具有高性能和友好部署的工业最先进的目标探测器。我们在之前的PP-YOLOv2的基础上进行优化&#xff0c;采用无锚模式&#xff0c;更强大的骨干和颈部配备CSPRepResSt…...

微服务入门---SpringCloud(二)

微服务入门---SpringCloud&#xff08;二&#xff09; 1.Nacos配置管理1.1.统一配置管理1.1.1.在nacos中添加配置文件1.1.2.从微服务拉取配置 1.2.配置热更新1.2.1.方式一1.2.2.方式二 1.3.配置共享1&#xff09;添加一个环境共享配置2&#xff09;在user-service中读取共享配置…...

51单片机IO口控制

51单片机IO口控制 1.点亮LED灯 原理&#xff1a;根据电路图&#xff0c;指向IO口的引脚&#xff1b;拉低电平&#xff0c;灯亮、 如图&#xff1a; [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zfco4IjK-1690308697530)(C:/Users/xie19/Pictur…...

ERROR 1064 - You have an error in your SQL syntax;

ERROR 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near (/, 少个逗号吧&#xff0c;以前开始写SQL&#xff0c;特别是修改SQL的时候容易出现这样错误。 而且自己也知道在附近…...

leetcode做题笔记46

给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 思路一&#xff1a;回溯 void swap(int *nums,int index1,int index2) {int temp nums[index1];nums[index1] nums[index2];nums[index2] temp; }void prem(int* nu…...

快问快答JS面向对象面试题

1、说说你对闭包的理解 使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染&#xff0c;缺点是闭包会常驻内存&#xff0c;会增大内存使用量&#xff0c;使用不当很容易造成内存泄露。在js中&#xff0c;函数即闭包&#xff0c;只有函数才会产生作用…...

googlenet论文理解

参考文章&#xff1a;https://www.cnblogs.com/czy4869/p/8977788.html 以及下面这篇的前几行让我弄懂了论文里说的稀疏性和计算性能兼顾&#xff1a;参考文章&#xff1a;https://blog.csdn.net/weixin_52121118/article/details/119740279...

OnnxRuntime TensorRT OpenCV::DNN性能对比(YoloV8)实测

1. 前言 之前把ORT的一套推理环境框架搭好了,在项目中也运行得非常愉快,实现了cpu/gpu,fp32/fp16的推理运算,同onnx通用模型在不同推理框架下的性能差异对比贴一下,记录一下自己对各种推理框架的学习状况 YoloV8模型大小 模型名称参数量NANO3.2M...... 2. CPU篇 CPU推理框架性…...

【QT 网络云盘客户端】——获取用户文件列表信息

目录 1.获取用户文件列表信息分析 2.设置图标属性 3.向服务器获取文件的数量 4.向服务器获取文件信息列表 4.显示图标 1.获取用户文件列表信息分析 1.将QListWidget设置为图标模式 2. 当我们点击"按下载量升序","按下载量降序",“更新” 菜单选项 都会…...

从0到1,无代码开发如何简化产品创新流程

在当今竞争激烈的市场环境中&#xff0c;产品创新已经成为企业成功的关键因素之一。为了在市场上保持竞争力&#xff0c;企业需要不断地推出新产品或改进现有产品。然而&#xff0c;传统的开发流程往往耗时费力&#xff0c;且成本高昂。因此&#xff0c;简化产品创新流程成为了…...

select、epoll 的快速核心理解

一、 select 最low的就是在用户代码中自旋实现所有阻塞socket的监听。但是每次判断socket是否产生数据&#xff0c;都涉及到用户态到内核态的切换。 于是select改进&#xff1a;将fd_set传入内核态&#xff0c;由内核判断是否有数据返回&#xff1b; 然后最low的只能使用自旋…...

HTTP和HTTPS的区别

一、两者概念 1.1 HTTP概念 HTTP 的全称是超文本传输协议&#xff08;HyperText Transfer Protocol&#xff09; 是一种用于分布式、协作式和超媒体信息系统的应用协议&#xff0c;简单来说就是一种分布和接收HTML页面的方法&#xff0c;被用于在Web浏览器和网站服务器之间传递…...

分布式异步任务处理组件(二)

一些关键点的设计脑暴记录----very important&#xff01;&#xff01;&#xff01; 首先&#xff0c;任务存储交给kafka&#xff0c;由节点负责写入kafka&#xff0c;acks1&#xff1b;失败重试&#xff1b;透传kafka的提交可靠性&#xff0c;保证任务提交成功&#xff1b;后…...

Jenkins 拉取 GitHub 私有仓库失败问题

添加仓库的时候提示 stderr: fatal: Cannot prompt because user interactivity has been disabled. 把在 GitHub账户设置中生成的个人访问令牌填到地址里...

小程序 多层次对象数组的赋值、动态赋值

1、给对象赋值 data: {form: {Name: ,IDCard: ,Sex: ,}},对单个属性赋值 this.setData({form.Name:章三,[form.Sex]:女,}) 动态赋值 onChangeDate(e) {let field e.currentTarget.dataset.field;this.setData({[form.${field}]: e.detail.data})}, field 是wxml上通过dat…...

angular踩坑

1 新版路由守卫由于canActivate已被废弃&#xff0c;采用函数函数&#xff0c;但其参数中无法像类一样进行路由对象注入&#xff0c;如何实现路由首位中的页面跳转&#xff1f; import { CanActivateFn,Router,ActivatedRouteSnapshot, RouterStateSnapshot,} from angular/ro…...

C#时间轴曲线图形编辑器开发1-基本功能

目录 一、前言 1、简介 2、开发过程 3、工程下载链接 二、基本功能实现 1、绘图面板创建 &#xff08;1&#xff09;界面布置 &#xff08;2&#xff09;显示面板代码 &#xff08;3&#xff09; 面板水平方向、竖直方向移动功能实现 &#xff08;4&#xff09;面板放…...

elasticsearch查询操作(DSL语句方式)

说明&#xff1a;本文介绍在kibana&#xff0c;es的可视化界面上对文档的查询操作&#xff1b; 添加数据 先使用API&#xff0c;创建索引库&#xff0c;并且把数据从MySQL中查出来&#xff0c;传到ES上&#xff0c;参考&#xff08;http://t.csdn.cn/NaTHg&#xff09; 索引库…...

JavaScript详解

目录 一、JavaScript是什么&#xff1f; 1.1、JavaScript 和 HTML 和 CSS 之间的关系 1.2、JavaScript 运行过程 1.3、JavaScript 的组成 二、JavaScript 的书写形式 1. 行内式 2. 内嵌式 3、外部式 注释 三、输入输出 输入: prompt 输出: alert 输出: …...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

如何理解 IP 数据报中的 TTL?

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