排序进阶----插入排序,希尔排序

news2025/1/16 19:54:11

       各位看官们好,接下来鄙人想与大家分享的实现被称为六大排序之一的插入排序。其实关于这六大排序在我们最开始就已经接触过了。我们在最开始学习c语言的时候,我们要学习到其中之一的冒泡排序。虽然现在看起来冒泡排序确实是没有太大的实际效果,但是对于我们入门却还是有很大的帮助的。而我们下来介绍的插入排序这是比排序好很多的一个优质排序方法。那废话少说,们来看看插入排排序是如何实现的,并且在实现插入排序后,再看看比插入排序额还厉害的希尔排序

6c0ce7e7f5d14bab9539ea8a07f94f99.jpeg

插入排序思路 

        对于插入排序的话其实还算是比较好理解的。我想大家应该都玩过扑克牌吧。斗地主大家都知道,我们平常的习惯都是按大小排序。这个其实就是插入排序。大家可以想一下,我们如果以扑克牌为例,我们利用冒泡排序的话,每一个位置就要对比一下,这很麻烦,很耗时间的。但是如果我用插入排序的话,我们以第一个数为例,一次向后对比,如果他比接下来对比的数都大的话,那么我就先把战船一直比较比他更大的数,那么我就把它插入在前面。意思就是相当我们暂时把整个数组看着是有序的。那这个数一直对比,一直到遇到比他大的我在插入。在没遇见之前,我就一直想把它存起来。如果都他是最大的话,那么遇到最后一个循环,那么就结束。

      我想我这么说可能是比较难以理解的,大家可以看一下下面这张动图来理解一下。

afae4b37f7034ff18b12ca93ac553ca4.gif

         这样大家可能会理解起来比较简单一些。而且如果大家对数据机构有一点了解的话,就知道插入排序的时间复杂度最坏也才 O(n^2)。那么接下来我们就来尝试一下如何把插入排序写出来。

插入排序实现

         那么我们想想如何实现插入排序呢?我们先从第一趟开始,比如说我们就先走第一趟,以下标为零开始的与下标为一对比,如果他比第一个大的话,那么这一趟就结束,我们就只循环一次。下一次循环我们就循环两次,以下交换后的下标再次循环。如果比前面的数小的话,那么就结束循环。

void InsertSort(int* arr, int n)
{
		int end = 0;
		//待插入的元素
		int tem = arr[end + 1];
		//单趟排
		while (end >= 0)
		{
			//比插入的数大就向后移
			if (tem < arr[end])
			{
				arr[end + 1] = arr[end];
				end--;
			}
			//比插入的数小,跳出循环
			else
			{
				break;
			}
		}
		arr[end + 1] = tem;
}

        这就是插入排序的单次排序。那么我们肯定不是循环一次就能将整个数组变为有序的。那么我就要多循环几次。我们可以看到我们代码最开始是以end开始的。我们把and设为0,那么它就是下标为0与下标为一对比,如果不能将它设为1,那么它就是与下面为1和下面为2对比。那我们就可以再写一个循环,将单次循环放进这个循环里面,End随循环次数增加,但是总体次数要小于我们传入的n小于1。因为我们自己设的要对比的下一个数就是end加一。如果我们这样最开始就是因为小于的话,那么会突出一个随机值。那么这样我们代码就是有问题了。 

void InsertSort(int* arr, int n)
{
	for (int i = 0; i < n - 1; ++i)
	{
		//记录有序序列最后一个元素的下标
		int end = i;
		//待插入的元素
		int tem = arr[end + 1];
		//单趟排
		while (end >= 0)
		{
			//比插入的数大就向后移
			if (tem < arr[end])
			{
				arr[end + 1] = arr[end];
				end--;
			}
			//比插入的数小,跳出循环
			else
			{
				break;
			}
		}
		//tem放到比插入的数小的数的后面
		arr[end + 1] = tem;//为什么写在外面,这是因为防止我们后面有一个最小的数,如果写在里面的话,那么end会减到-1.那么就跳出循环了,无法交换。所以写在外面是防止这样的情况
		//代码执行到此位置有两种情况:
		//1.待插入元素找到应插入位置(break跳出循环到此)
		//2.待插入元素比当前有序序列中的所有元素都小(while循环结束后到此)
	}
}

7c07b8b4340540818b56acd4878f8ba6.png

        这是我设的一个插入排序的一个示例。当然这些里面的势力还算比较简单的,还不足以体现插入排序的优势。但是大家知道冒泡排序是我们六大排序中速度最慢的。我们学会了插入排序,后面如果对希尔排序,如果不了解的话,插入排序也算是一个较好的排序方法。 

      补充:我想大家可能会对代码中的有一个有疑问,就是为什么插入的数大于的话后移,后要end减减嘞。这个是因为我们排序就是下标为1的与下标为0的对比然后交换。是从后向前交换,与冒泡排序的从前往后交换。所以我们第一次是只交换一次。并且大家需要注意的是我在上面还的代码中的,为什么将arr[end + 1] = tem;写在外面。

希尔排序思路

        对于希尔排序来说啊,这其实超过了我们普通人或一般学霸的认知了。其实虽然我们有想可能会想过对一些很混乱的数组我们先给他排简单排一下,然后再进行排序。但是我们简单排序,怎么给他简单排序了?而且反正都要排序的。那不是浪费更多的时间吗?反正这是我个人是这么想的。他也正是因为我们都能想到可以给它初排序一下。但是我们初排序是如何排的呢?我们却并没有想过。但是希尔他就想过了。他想将一个数组用gap(一个数)来个开。就好比是下面这个样子。df89755290ad478c8f849e17f731272b.png

        然后我们以两个节点来对比进行交换。而且我们再将移动到下一个下标。并且也以gap隔离来进行节点交换,这样就完成了我们的初排序。大家可以想象这样是不是就形成了一个相对比较有序的数组?ed9afe30a0c74883976110e39593c2b1.png

        但是大家也知道,我们这个开始想的也就是初排序。我们还需要一个实际排序呀。那么就要用我们上面写的插入排序了。我们插入排序是与下一个进行对比,那我们希尔排序中间隔了gap后再进行对比交换的。那么不知道大家是否要联想到希尔排序与插入排序为基础来实现写的? 

        好了,我们初入排序写了,那么我们接下来该怎么操作呢?我们每一次单趟的gap是确定的。那么如果我们这样第二堂的gap设为第一堂gap的3分之一。那么我们是不是就会比较细一点了?但是我们想想是不是有时候有些时候被3初了会为零,不会为1。那么我们就没有再具体走一遍,是吧?所以我们在除以下之后再加一,那么我们是不是就能保证最后一次为1了。这样我们是不是就最后将整个排序实现了。

14637ac288f0449e9f239d7a77da2e78.gif

希儿排序实现 

       那么上面我们居然写了大概思路。我们还是想插入排序一样,先写单趟如何实现。

void ShellSort(int* arr, int size)
{
	    int gap = 3;
		int i = 0;
		for (i = 0; i < size - gap; i++)	//从0遍历到size-gap-1
		{//为什么是小于size-gap。因为当我们size本来就大于数组个数一个,减去gap后的数就是临界点了,再加一个gap的话就超界了。大家可以想想。
			int end = i;//是不是就是插入排序啊
			int temp = arr[end + gap];
			while (end >= 0)
			{
				if (arr[end] > temp)
				{
					arr[end + gap] = arr[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			arr[end + gap] = temp;	//以 end+gap 作为插入位置
		}
}

       不知道大家看到这个是我觉得很熟悉啊,是不是?像我们上面写的插入排序?就是将插入排序中的一改为了gap。是不是就实现了我们说的gap节点,然后进行对比交换了。 那么我们实现了单次排序之后,我们下一次排序。我们在上面说过gap是会变的。一直到为1就成为最后的插入排序,这个大家了解吧。那么就简单了,我们只需要再写一个循环,在循环的时候这样每一次gap进去之后进行改变。

void xixi(int* arr, int size)
{
	int gap = size;
	while (gap > 1)
	{
		gap = gap / 3 + 1;//没进行一次gap后,gap进行改变
        int i = 0;
		for ( i = 0; i < size - gap; i++)
		{
			int end = i;
			int tmp = arr[end + gap];
			while (end >= 0)
			{
				if (arr[end]>tmp)
				{
					arr[end + gap] = arr[end];
					end-=gap;
				}
				else
				{
					break;
				}
			}
			arr[end + gap] = tmp;
		}
	}
}

        这样大家应该能了解了吧。希尔排序简单一点,也就是说我们先以gap为跨点进行一次大的排序,然后再依次减少,依次减少。这样原本乱序的数组就成为了相对有序的数组。最后我们就直接用插入排序,那样是不是就解决了这个问题了?

         所以大家只需要理解,我们先出了gap为1以前的都叫预处理。为1之后就是正式的排列了。  当然希尔排序其实是有一点困难的,大家需要多理解一点多看一下,其实相对还是比较简单的,只需要理解之后大家都能写出来的。

总结     

        好了,以上就是本篇博客想与大家分享的两个排序方法的。大家可以先着重了解插入排序,因为希尔排序是以插入排序为基础而推进发展的。当然如果大家对希尔还是不太了解的话,插入排序现在对目前来说还是很有用的,先了解他的话也是足够了的。好了,本篇博客肯定还有很多不足的地方,希望大家能在评论区留言,方便鄙人来更改。

 

 

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

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

相关文章

ROS无人机追踪小车项目开发实战 | 第四届中国智能汽车创新大会圆满结束

2024年5月26日&#xff0c;阿木实验室在深圳第四届中国智能汽车创新大会上&#xff0c;开展的《Prometheus开源平台-ROS无人机追踪小车项目开发实战课》圆满结束。 该实战课从初学者的角度出发&#xff0c;通过实践性讲解和开发&#xff0c;使开发者们系统地学习了硬件系统架构…

无需开孔,安全美观:低功耗微波雷达模块开启宠物喂食器新未来

在快节奏的现代生活中&#xff0c;宠物已成为许多家庭的重要成员。然而&#xff0c;忙碌的主人常常为如何确保宠物按时进食而困扰。近年来&#xff0c;智能家居技术飞速发展&#xff0c;宠物喂食器也逐渐智能化&#xff0c;极大地方便了宠物主人。今天&#xff0c;我们要介绍的…

读书 |《人工智能产品经理-AI时代PM修炼手册》

《人工智能产品经理——AI时代PM修炼手册》by张竞宇&#xff0c;read at 2020.04 这是今年准备面试时看的一本书了。全书从宏观层面介绍了AIPM应具备的的视野范围、一套较完备的工作方法论。AI领域的常识、日常工作没有超出这本书的范畴&#xff0c;是一本合格的入门科普书籍。…

Centos安装nvm管理node版本(让安装变得可控又快捷)

Centos安装nvm管理node版本&#xff08;让安装变得可控又快捷&#xff09; 没有找到一个对的人&#xff0c;有可能是你没有走对那条路&#xff0c;也有可能是你没有睁开眼睛&#xff0c;而更大的可能是&#xff0c;你根本就没有出发去找。 安装说明 nvm安装目录&#xff1a;/us…

AI 画图真刺激,手把手教你如何用 ComfyUI 来画出刺激的图

目前 AI 绘画领域的产品非常多&#xff0c;比如 Midjourney、Dalle3、Stability AI 等等&#xff0c;这些产品大体上可以分为两类&#xff1a; 模型与产品深度融合&#xff1a;比如 Midjourney、Dalle3 等等。模型与产品分离&#xff1a;比如 SD Web UI、ComfyUI 等等。 对于…

ms sql server 2008数据库跨服务器迁移方法

一、直接拷贝数据法&#xff1a; 1、打开sql server management studio&#xff0c;选中要迁移的数据库; 2、先在源数据库里点 “脱机”&#xff0c;等到脱机成功后&#xff0c;直接到目录里&#xff08;默认路径是C:\Program Files\Microsoft SQL Server\MSSQL10.MSS…

LabVIEW异步编程概述

LabVIEW异步编程是一种在图形化编程环境中处理并行任务的方法。通过异步执行&#xff0c;可以提高程序的响应速度和资源利用效率&#xff0c;使得多个任务可以独立进行而不互相干扰。 原理 LabVIEW异步编程的核心在于使用异步调用节点&#xff08;Asynchronous Call By Refer…

AI绘画(Stable Diffusion)喂饭级教程-第2篇(SD大模型详解)

SD大模型的概念及基础知识 先做一个比喻 如果SD是一个画师&#xff0c;那么大模型就是画师的大脑&#xff01; 就是可惜&#xff0c;这个大脑有点轴&#xff0c;它只能想象出自己喜欢的画面。 比如你用了一个二次元的大脑&#xff0c;它想出来的画面就是这样的&#xff1a; …

嵌入式进阶——EEPROM读写

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 设置EEPROM读写String字符串官方示例 EEPROM是一种可擦写可编程只读存储器&#xff08;Electrically Erasable Programmable Read-…

源达投顾的客户服务质量怎么样?

在金融服务行业中&#xff0c;客户服务质量是衡量一个公司成功与否的关键因素之一。源达投顾作为一家专业的投资顾问机构&#xff0c;其客户服务质量一直备受关注。那么&#xff0c;源达投顾的客户服务质量怎么样&#xff1f; 一、客户满意度调查方法 为了全面、客观地了解源…

SurfaceView与TextureView的绘制渲染

SurfaceView与TextureView的绘制渲染 一.SurfaceView1.SurfaceView的初始化1.1 SurfaceControl的创建1.1.1 BLASTBufferQueue与SurfaceControl的绑定 1.2 Surface初始化 2.SurfaceHolder的回调与绘制2.1 画布的获取2.2 矩形的绘制2.3 绘制的提交 二.TextureView1.TextureView的…

一文搞懂Java8 Lambda表达式、方法引用

Lambda表达式介绍 Java 8的一个大亮点是引入Lambda表达式&#xff0c;使用它设计的代码会更加简洁。通过Lambda表达式&#xff0c;可以替代我们以前经常写的匿名内部类来实现接口。Lambda表达式本质是一个匿名函数&#xff1b; 体验Lambda表达式 我们通过一个小例子来体验下L…

物联网都有什么优缺点?——青创智通

工业物联网平台解决方案 物联网&#xff0c;这个曾经似乎遥不可及的科技概念&#xff0c;如今已逐渐渗透到我们生活的方方面面。从智能家居到智能工业&#xff0c;从智能医疗到智能城市&#xff0c;物联网技术正在改变着我们的世界。 然而&#xff0c;正如任何一项技术一样&a…

代码随想录算法训练营第五十四天||392.判断子序列、115.不同的子序列

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、392.判断子序列 思路 二、115.不同的子序列 思路 一、392.判断子序列 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是…

FPGA中的乒乓操作

为什么不直接选用一个缓存更大的FIFO而选用乒乓操作为什么乒乓操作可以实现低速处理高速数据乒乓操作适用哪些场景 一、乒乓操作结构 首先先介绍一下乒乓操作的原理&#xff0c;其结构如下&#xff1a; 输入选择单元负责将数据送到数据缓冲模块&#xff0c;然后输出选择单元负…

51 html网页

上节内容的网页是hello world的字符串&#xff0c;但实际上网页应该是html格式的这种超文本标记语言&#xff0c;这一节完善一下网页的各种格式和内容 分文件 实际服务器中&#xff0c;网页的界面应该单独放一个文件&#xff0c;服务器从文件里读取网页的内容 先创建一个wroo…

有效运营企业内部社区的板块有哪些?

随着企业内部沟通和协作的重要性日益凸显&#xff0c;建立一个高效运营的企业内部社区成为越来越多企业的首要任务。针对不同的需求和目标&#xff0c;将企业内部社区分为多个板块&#xff0c;可以更好地促进员工之间的沟通、协作和共享知识。下面介绍如何从分多个板块创建的角…

Docker搭建Redis主从 + Redis哨兵模式(一主一从俩哨兵)

我这里是搭建一主一从&#xff0c;俩哨兵&#xff0c;准备两台服务器&#xff0c;分别安装docker 我这里有两台centos服务器 主服务器IP&#xff1a;192.168.252.134 从服务器IP&#xff1a;192.168.252.135 1.两台服务器分别拉取redis镜像 docker pull redis 2.查看镜像 d…

2024长三角快递物流展即将亮相,致鸿物流器材有限公司值得关注

广东致鸿物流器材有限公司&#xff0c;前身为广州致鸿物流器材有限公司&#xff0c;成立于2002年初&#xff0c;是一家中国专业仓储笼研发制造公司&#xff0c;公司员工约400名&#xff0c;日产仓储笼制造规模近8000个&#xff0c;在全国范围内有五大配送服务中心&#xff1a;江…

AI绘画Stable Diffusion XL 可商用模型!写实艺术时尚摄影级真实感大模型推荐(附模型下载)

大家好&#xff0c;我是设计师阿威 大家在使用AI绘画的时候&#xff0c;是不是遇到这种问题&#xff1a;收藏的模型确实很多&#xff0c;可商用的没几个&#xff0c;而今天阿威将给大家带来的这款写实艺术时尚摄影级真实感大模型-墨幽人造人XL&#xff0c; 对于个人来讲完全是…