【数据结构】复杂度

🔥博客主页:小王又困了

📚系列专栏:数据结构

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

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


目录

一、什么是数据结构

二、什么是算法

三、算法的效率

四、时间复杂度

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);
}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/34055.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

k8s基础

k8s基础 文章目录 k8s基础一、k8s组件二、k8s组件作用1.master节点2.worker node节点 三、K8S创建Pod的工作流程&#xff1f;四、K8S资源对象1.Pod2.Pod控制器3.service && ingress 五、K8S资源配置信息六、K8s部署1.K8S二进制部署2.K8S kubeadm搭建 七、K8s网络八、K8…

人大金仓三大兼容:Oracle迁移无忧

企业级应用早期的架构模式是C/S&#xff08;Client/Server&#xff09;模式&#xff0c;Client做人机交互逻辑的呈现&#xff0c;Sever做业务计算逻辑的实现。这就类似餐馆的运作模式&#xff0c;Client是前台的服务员提供点菜和上菜服务&#xff0c;而Server则是后厨完成菜品的…

设计模式之工厂方法模式(FactoryMethod)

一、概述 定义一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。FactoryMethod使一个类的实例化延迟到其子类。 二、适用性 1.当一个类不知道它所必须创建的对象的类的时候。 2.当一个类希望由它的子类来指定它所创建的对象的时候。 3.当类将创建对象的职责委…

Stable Diffuion webui Mac版本安装过程

系统环境 操作系统&#xff1a;MacOS Ventura13.5 芯片&#xff1a;Apple M2 Max Python: 3.10 安装前置准备 git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git注意事项&#xff1a;修改源码内全部 git clone 链接&#xff0c;设置代理 https://ghpr…

Fast SAM与YOLOV8检测模型一起使用实现实例分割以及指定物体分割

Fast SAM与YOLOV8检测模型一起使用 部分源代码在结尾处可获取 晓理紫 1 使用场景 实例分割数据集的获取要比检测数据的获取更加困难&#xff0c;在已有检测模型不想从新标注分割数据进行训练但是又想获取相关物体的mask信息以便从像素级别对物体进行操作&#xff0c;这时就可以…

学习内容散记

git下载网址 &#xff1a;https://registry.npmmirror.com/binary.html?pathgit-for-windows/ error: remote origin already exists 如果你clone下来一个别人的仓库&#xff0c;在此基础上完成你的代码&#xff0c;推送到自己的仓库可能遇到如下问题&#xff1a; error: r…

uniapp开发(由浅到深)

文章目录 1. 项目构建1.1 脚手架构建1.2 HBuilderX创建 uni-app项目步骤&#xff1a; 2 . 包依赖2.1 uView2.2 使用uni原生ui插件2.3 uni-modules2.4 vuex使用 3.跨平台兼容3.1 条件编译 4.API 使用4.1 正逆参数传递 5. 接口封装6. 多端打包3.1 微信小程序3.2 打包App3.2.1 自有…

支付整体架构

5.4 支付的技术架构 架构即未来&#xff0c;只有建立在技术架构设计良好的体系上&#xff0c;支付机构才能有美好的未来。如果支付的技术体系在架构上存在问题&#xff0c;那么就没有办法实现高可用性、高安全性、高效率和水平可扩展性。 总结多年来在海内外支付机构主持和参与…

C语言之位运算

一、什么是位运算 所谓位运算是指进行二进制位的运算 在系统软件中&#xff0c;常要处理二进位的问题 例如&#xff0c;将一个存储单元中的各二进位左移或右移一位&#xff0c;两个数按位相加等 二、位运算符和位运算 1、按位与 运算符(&) 参加运算的两个数据&#xff…

Exploiting Proximity-Aware Tasks for Embodied Social Navigation 论文阅读

论文信息 题目&#xff1a;Exploiting Proximity-Aware Tasks for Embodied Social Navigation 作者&#xff1a;Enrico Cancelli&#xff0c; Tommaso Campari 来源&#xff1a;arXiv 时间&#xff1a;2023 Abstract 学习如何在封闭且空间受限的室内环境中在人类之间导航&a…

uniapp 获取 view 的宽度、高度以及上下左右左边界位置

<view class"cont-box"></view> /* 获取节点信息的对象 */ getElementRect() {const query uni.createSelectorQuery().in(this);query.select(".cont-box").boundingClientRect(res > {console.log(res);console.log(res.height); // 10…

mysql数据库第十二课------mysql语句的拔高2------飞高高

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

研发工程师玩转Kubernetes——通过PV的节点亲和性影响Pod部署

在《研发工程师玩转Kubernetes——PVC通过storageClassName进行延迟绑定》一文中&#xff0c;我们利用Node亲和性&#xff0c;让Pod部署在节点ubuntud上。因为Pod使用的PVC可以部署在节点ubuntuc或者ubuntud上&#xff0c;而系统为了让Pod可以部署成功&#xff0c;则让PVC与Pod…

Spring-Cloud-Loadblancer详细分析_2

LoadBalancerClients 终于分析到了此注解的作用&#xff0c;它是实现不同服务之间的配置隔离的关键 Configuration(proxyBeanMethods false) Retention(RetentionPolicy.RUNTIME) Target({ ElementType.TYPE }) Documented Import(LoadBalancerClientConfigurationRegistrar…

Mongodb:业务应用(1)

环境搭建参考&#xff1a;mongodb&#xff1a;环境搭建_Success___的博客-CSDN博客 需求&#xff1a; 在文章搜索服务中实现保存搜索记录到mongdb 并在搜索时查询出mongdb保存的数据 1、安装mongodb依赖 <dependency><groupId>org.springframework.data</groupI…

Intellij IDEA 导入 eclipse web 项目详细操作

Eclipse当中的web项目都会有这两个文件。但是idea当中应该是没有的&#xff0c;所以导入会出现兼容问题。但是本篇文章会教大家如何导入&#xff0c;并且导入过后还能使用tomcat运行。文章尽可能以图片的形式进行演示。我的idea使用的版本是2022.3.3版本。当然按正常来说版本之…

C++ ModBUS TCP客户端工具 qModMaster 介绍及使用

qModMaster工具介绍 QModMaster是一个基于Qt的Modbus主站&#xff08;Master&#xff09;模拟器&#xff0c;用于模拟和测试Modbus TCP和RTU通信。它提供了一个直观的图形界面&#xff0c;使用户能够轻松设置和发送Modbus请求&#xff0c;并查看和分析响应数据。 以下是QModM…

图论——最短路算法

引入&#xff1a; 如上图&#xff0c;已知图G。 问节点1到节点3的最短距离。 可心算而出为d[1,2]d[2,3]112,比d[1,3]要小。 求最短路径算法&#xff1a; 1.Floyd(弗洛伊德) 是一种基于三角形不等式的多源最短路径算法。边权可以为负数 表现为a[i,j]a[j,k]<a[i,k]。 …

什么是响应式设计?列举几种实现响应式设计的方法。

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是响应式设计&#xff1f;⭐ 实现响应式设计的方法⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏…

Docker安装ElasticSearch/ES 7.4.0

目录 前言安装ElasticSearch/ES安装步骤1&#xff1a;准备1. 安装docker2. 搜索可以使用的镜像。3. 也可从docker hub上搜索镜像。4. 选择合适的redis镜像。 安装步骤2&#xff1a;拉取ElasticSearch镜像1 拉取镜像2 查看已拉取的镜像 安装步骤3&#xff1a;创建容器创建容器方…