数据结构——排序(4)

news2025/6/9 13:37:44

作者:几冬雪来

时间:2023年4月12日

内容:数据结构排序内容讲解

目录

前言: 

1.快速排序中的递归:

2.小区间优化: 

3.递归改非递归: 

4.归并排序: 

5.归并排序的非递归形式(框架): 

结尾: 


前言: 

在前一篇博客中我们对快速排序的代码进行了一步优化,将它优化出来了3种方法——随机找key法,三数取中法和前后指针法。而在今天,我们则在已经优化过的基础上,对我们的代码进行进一步的优化。 

1.快速排序中的递归:

在我们之前书写快速排序的时候,每次都是先写一趟快速排序而后再使用递归的方法让我们的数组通过几次快速排序后一步步变得有序。而我们的这个递归的行为则类似我们的二叉树的操作,越往下走递归的次数越多。 

而在我们二叉树的那个板块曾经就有说明过,当我们递归次数很多的时候,最后一层的递归出来的结果个数是我们总数的一半,往上到倒数第二层是1/4,再然后是1/8

那么在这里就有人提了一个建议,就是在我们快速排序排到最后倒数第4层的时候我们就不再继续往下递归下去了,之后无序的数组我们用直接插入排序来将其变得有序这样子做就可以大大的减少我们的递归的次数

这种方法就被我叫做——小区间优化。 

2.小区间优化: 

最小区间法,顾名思义就是当我们的区间变得较小的时候,这里用其他的排序来代替我们的快速排序。那么在这里,我们就将它们的代码写出来。

这里就是我们的小区间优化法,在这里我们有需要小心的地方,也存在着我们可以普及的内容,接下来我们就来一一细说一下。 

在这里我们的元素的个数是可以进行修改的。这里的大于10也可以修改为大于20或者是50,但是如果在这里进行了修改的话,我们的小区间优化法可能会适得其反

这里要注意的是,如果区间个数过多,可能会导致这里小区间优化法的运行时间比没有小区间优化法的时间要长。且原数组元素个数少的话,小区间优化法的优化程度及其有限,当原数组的元素个数多的时候,小区间优化法才能更好的表现出来它的优势

但是在这里我们不单单是讲小区间优化法的问题,我们是要依靠它来引出一个新的问题。

3.递归改非递归: 

因为我们的快速排序所运用的方法是递归,所以这里就牵扯出来一个经典的问题——栈溢出。当我们的递归次数过多的时候,哪怕我们的代码是对的,但是它在debug中依旧也是跑不起来。栈的内存满了,我们的代码也会调试不起来,因此针对程序员而言,如果某个程序的递归没问题我们就不需要管它,相反如果出现问题的话,我们要学会将我们的递归改为非递归

而在这里我们用到的知识则是栈板块的知识。 

首先我们要把栈的头文件和.c文件一起复制到我们当前文件中。接下来就要开始我们非递归的操作了。这里要用循环来代替我们的递归,第一个要想到的是,在递归中我们递归的是什么东西,而在快排当中我们递归的对象是区间(对象不是数组因为数组不在栈中)。 因此我们的栈也要存区间。

这就是我们非递归形式的快速排序的操作过程,第一次先将0和9存放到栈中,然后将其取出,找到我们的key后将其分为左右区间,接下来再把6和9先存放到栈中,而后存放0和4,下来我们继续以上的操作,直到最后我们的区间只剩下一个值或者不存在就结束。 

知道这些操作之后下来就是书写我们的代码了。 

这就是我们的代码和它的讲解了,虽然这里我们的代码从递归形式改为非递归形式,但是实际上它的效率并没有什么提升,非递归形式只是防止栈溢出罢了。 

4.归并排序: 

接下来要讲解的排序是我们的归并排序,归并排序也是我们一种十分有效的排序方法。 

接下来是我们归并排序的操作图。 

在这里我们将我们的数组拆为平均两个部分,然后判断两个部分是否有序,无序的话就继续往下拆分,直到我们拆分下最后一个数的时候,这里我们就开始回归,回归的时候我们的每个区间都会变得有序。 

当最后我们合并剩下两个区间的时候,我们最后再把它们进行一次合并排序,最后我们的数组就可以变得有序起来了。 

同样的在这里我们的归并排序的时间复杂度也为标准的O(N*logN)。因为在这里我们每层需要排序的个数都为N,并且每次排序都是将区间平均的一分为二,所以它的时间复杂度是logN。 

在归并排序中有人看我们的这个图片,以为每次分解都要建立一个小数组,但是其实不是的。

在这里我们只需要一个临时数组来帮助我们进行排序,每次排序之后我们就要将我们的内容给拷贝出去。当最后归并到我们的左右都有序之后,将它拷贝回原数组中,它就有序了。接下来就是来书写我们的代码了和其解析。 

这就是我们的代码和它的解析了,这里需要注意的是,在这里我们每次递归都是要用到整个数组的元素,因此在判断那里我们需要用到等于号。 

这里我们用的数组刚刚好可以被我们平均的拆分为2个大小相等的数组,如果这里数组中元素的个数是单数的话,我们的代码依旧可以跑起来吗? 

这里从结果中可以看出,哪怕我们的数组元素的个数是单数的,我们依旧可以通过这种方法对我们的数组进行排序,它并不影响我们排序的进行。 

5.归并排序的非递归形式(框架): 

同样的在这里,我们的归并排序也有它的非递归形式。在前面我们讲到,递归变循环我们又两种方法,一种的借助栈来进行修改,另外一种则是直接修改,而在这里归并排序的非递归形式是自己对其进行修改

这里我们又一个方法。

在这里我们取一个gap值,每次归并后我们的gap值增加,我们每次参与归并的元素个数也随之增加。 就类似我们上图这样,不过这种方法有需要修改的点,比如边界问题等,我们就留到下一篇博客来讲解了

接下来我们就来浅浅的写一写我们的代码和它的解析。 

这就是我们归并排序非递归形式代码的一个大体的框架,这其中还存在着很多的问题。这些我们就留到下一篇博客再来讲解吧。 

结尾: 

到这里我们的数据结构的内容就再一次的讲解完毕了,很快的我们的数据结构排序板块的内容就要结束了,后面我们还要对我们的归并排序的非递归形式进行优化。最后希望这篇博客能为大家带来一点的帮助。 

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

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

相关文章

Revit中如何绘制倾斜的屋顶及一键成板?

Revit中如何绘制倾斜的屋顶?如下图所示,像这种坡屋顶有两种方法进行绘制。 第一种:定义坡度。 1、点击建筑选项卡中的屋顶按钮。选择使用矩形工具。 2、在选项栏中,偏离值修改为500,把屋顶迹线绘制出来。 3、取消这三…

软件测试今天你被内卷了吗?

认识一个人,大专学历非计算机专业的,是前几年环境好的时候入的行,那时候软件测试的要求真的很低,他那时好像是报了个班,然后入门的,但学的都是些基础,当时的他想的也简单,反正也能拿…

【面试】限流算法有哪些?

文章目录前言1.固定窗口限流算法1.2 固定窗口限流的伪代码实现1.2 固定窗口算法的优缺点2.漏桶算法3.令牌桶算法4. 滑动窗口限流算法4.1 什么是滑动窗口限流算法4.2 滑动窗口限流算法的伪代码实现4.3 滑动窗口限流算法的优缺点漏桶算法 VS 令牌桶算法总结参考 & 鸣谢前言 …

docker项目实施

鲲鹏916架构openEuler-arm64成功安装docker并跑通tomcat容器_闭关苦炼内功的技术博客_51CTO博客鲲鹏916架构openEuler-arm64成功安装docker并跑通tomcat容器,本文是基于之前这篇文章鲲鹏920架构arm64版本centos7安装docker下面开始先来看下系统版本卸载旧版本旧版本…

刘二大人《Pytorch深度学习实践》第八讲加载数据集

文章目录Epoch、Batch-Size、IterationsDataset、DataLoader课上代码torchvision中数据集的加载Epoch、Batch-Size、Iterations 1、所有的训练集进行了一次前向和反向传播,叫做一个Epoch 2、在深度学习训练中,要给整个数据集分成多份,即mini-…

【密码学】ElGamal加密算法原理 以及 例题讲解

目录前言1. 原理2. 例题2.1 例题一2.2 例题二前言 具体的性质: 非对称加密算法应用于一些技术标准中,如数字签名标准(DSS)、S/MIME 电子邮件标准算法定义在任何循环群 G 上,安全性取决于 G 上的离散对数难题 1. 原理…

元宇宙地产暴跌,林俊杰亏麻了

文/章鱼哥出品/陀螺财经随着元宇宙的兴起,元宇宙地产曾一度被寄予厚望,成为各大投资者追捧的对象。然而,最近的一次元宇宙地产价值暴跌再次提醒我们,高收益背后可能伴随着高风险。根据元宇宙分析平台WeMeta的数据显示,…

400以内的蓝牙耳机哪款好?400以内蓝牙耳机排行榜

谈起TWS,无论是传统的音频厂商还是手机厂商,都是其不可或缺的重要产品线,现在很多许多蓝牙耳机都不是千篇一律得形状,市场也鲜有商家在外观上下功夫,下面分享几款400元以内,内外兼具的耳机品牌。 一、南卡…

Spring boot+Vue3博客平台:修改密码与找回密码的设计与实现

修改密码与找回密码功能的设计与实现涉及到前后端的配合。本文将详细介绍如何通过设计思路、技术实现和代码示例实现这两个功能。 一、修改密码功能 设计思路 在设计修改密码功能时,需要注意以下几点: 用户输入的当前密码需要正确新密码需要满足一定的…

查询优化器:选择最优的查询路径

当我们通过解析器理解了SQL语句要干什么之后,接着会找查询优化器(Optimizer)来选择一个最优的查询路径。 可能有同学这里就不太理解什么是最优的查询路径了,这个看起来确实很抽象,当然,这个查询优化器的工…

总结819

学习目标: 4月(复习完高数18讲内容,背诵21篇短文,熟词僻义300词基础词) 第二周: 学习内容: 暴力英语:早上背诵《think different》记150词,默写了两篇文章&#xff0c…

BUUCTF-warmup_csaw_2016

1.checksec/file 64位的linux文件 2.ida 找到主函数 发现致命函数 get() 因为get可以无限输入 看看有没有什么函数我们可以返回的 双击进入sub_40060d 直接发现这个函数是取flag的 所以我们开始看这个函数的地址 所以函数地址是 0x40060d 我们看看get什么时候开始的 发现g…

Stable Diffusion复现——基于 Amazon SageMaker 搭建文本生成图像模型

众所周知,Stable Diffusion扩散模型的训练和推理非常消耗显卡资源,我之前也是因为资源原因一直没有复现成功。而最近我在网上搜索发现,亚马逊云科技最近推出了一个【云上探索实验室】刚好有复现Stable Diffusion的活动,其使用亚马…

超详细从入门到精通,pytest自动化测试框架实战-fixture高级进阶(十)

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 1、fixture的autous…

jQuery+AJAX技术(简单的用户注册功能)

目录1、jQuery是什么?2、AJAX是什么?3、jQuery与AJAX的关系?使用jQuery实现AJAX示例:4、jQueryAJAX技术实现用户注册验证功能。1、jQuery是什么? jQuery 是一个快速,小型且功能丰富的JavaScript库。它使 诸…

gradle编译项目报错Execution failed for task ‘:bootJar‘,‘:mainClass‘,‘:compileJava‘.

目录1.问题2.问题查找3.更多1.问题 idea导入Gradle管理的SpeingBoot多模块项目,依赖下载不下来,执行编译报错 报错信息: 2.问题查找 首先怀疑是不是idea的版本与gradle版本冲突,我用的是idea2022.3.3,gradle是7.5.…

做一个内心强大的人

想想类似如下这种心灵鸡汤,本不太愿意在这个平台发布,但是偶尔喝点又何尝不可! 语录摘抄/分享: 1、你开始炫耀自己,往往都是灾难的开始,就像老子在《道德经》里写到: 光而不耀,静水流深。 2、…

汽车电子相关术语介绍

一、相关术语介绍 1、汽车OTA 全称“Over-The-Air technology ”,即空中下载技术,通过移动通信的接口实现对软件进行远程管理,传统的做法到4S店通过整车OBD对相应的ECU进行软件升级。OTA技术最早2000年出现在日本,目前通过OTA方式…

HashMap源码解析超详细

HashMap源码详解1、概述2、源码解析1.HashMap底层存储结构问题一: 为什么直接就用数组呢?问题二:什么是红黑树呢?问题三:为什么不一下子把整个链表变为红黑树呢?2.HashMap的重要成员变量3.构造方法解析4.Put方法解析取…

渗透测试工具库-收藏版

1.前言 浩二一开始做渗透测试的时候收集超多的资料和工具,一直在文档里吃灰。今天全部放出来分享给大家,需要的自己收藏。 2.漏洞练习平台 WebGoat漏洞练习平台: https://github.com/WebGoat/WebGoat webgoat-legacy漏洞练习平台: http…