【排序算法】——插入排序

目录
前言
简介
基本思想
1.直接插入排序
2.希尔排序
代码实现
1.直接插入排序
2.希尔排序
总结
1.时空复杂度
2.稳定性
尾声
前言
排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列。所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
排序算法,就是如何使得记录按照要求排列的方法。排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面。一个优秀的算法可以节省大量的资源。
简介
所谓排序算法,即通过特定的算法因式将一组或多组数据按照既定模式进行重新排序。这种新序列遵循着一定的规则,体现出一定的规律,因此,经处理后的数据便于筛选和计算,大大提高了计算效率。对于一个排序算法的优劣,我们需要从它的时间复杂度、空间复杂度和稳定性三个方面来考虑。什么叫稳定性呢?即当两个相同的元素同时出现于某个序列之中,则经过一定的排序算法之后,两者在排序前后的相对位置不发生变化。换言之,即便是两个完全相同的元素,它们在排序过程中也是各有区别的。
本篇文章讲述的是排序算法中的插入排序,其中包含了两种排序算法,分别是直接插入排序和希尔排序,下面将会一一为大家详细介绍。(用升序进行讲解)
插入排序算法是基于某序列已经有序排列的情况下,通过一次插入一个元素的方式按照原有排序方式增加元素。这种比较是从该有序序列的最末端开始执行,即要插入序列中的元素最先和有序序列中最大的元素比较,若其大于该最大元素,则可直接插入最大元素的后面即可,否则再向前一位比较查找直至找到应该插入的位置为止。
基本思想
插入排序的基本思想是,每次将1个待排序的记录按其关键字大小插入到前面已经排好序的序列中,寻找最适当的位置,直至全部记录插入完毕。
1.直接插入排序
下面我们首先来看一看直接插入算法的动图演示:

看了上图之后,我们可以得知,直接插入排序是在一个给定的数组中,我们从第二个元素开始,与之前的元素一一进行比较:
· 若是该位置的元素小于前一个元素,那么就将该位置元素与更前一位的元素再次进行比较,直到前面没有元素,那么此时该元素就放在数组的首位。
· 若是该位置的元素大于或者等于前一个元素,那么就把该位置的元素放到前一个元素的后面(具体的方式在下面的代码实现中进行讲解)。
这就是直接插入排序的具体思路,有了它我们便可以写出我们的直接插入排序算法。
2.希尔排序
当数组中的元素越接近有序时,直接插入排序算法的时间效率越高;但是当数组中的元素越不接近有序,特别是倒序时,此时要使元素正序排列,使用直接插入算法的时间效率就非常低了,那我们能不能对直接插入算法进行一些优化呢?
答案是可以的。既然我们说当元素越有序时的时间效率越高,那我们可以把元素先分为若干份,先将这些部分使用直接插入算法变得有序后再去整体进行直接插入排序算法,从而达到目的,这就是希尔排序。
希尔排序法又称缩小增量法。希尔排序算法的基本思想是:先选定一个整数,记为num,用num计算出一个距离gap = n / num + 1,n为元素总数,把待排序元素分成各组,所有的距离相等的记录分在同一组内,并对每⼀组内的元素进行排序,然后gap = gap / num + 1得到下⼀个距离,再将数组分成各组,进行直接插入排序,当gap == 1时,就相当于直接插入排序。举个例子,此时我们的num取2,先看下面图片

上图中n = 10,我们选取一个整数2计算得到第一个距离gap = 10 / 2 + 1 = 5,此时第一个元素9和与他距离为5的第六个元素4为一组,6 + 5 = 11,由于数组中只有十个元素,因此第一组中只有两个元素,9和4,后面以此类推。将这些组分别进行直接插入排序后我们更新gap = gap / 2 + 1 = 2,此时相距为2的元素为一组,再次对每一组进行直接插入排序,直到gap == 1,此时再进行直接插入排序,这样,我们就完成了希尔排序算法。当 gap > 1 时都是预排序,目的是让数组更接近于有序。当 gap == 1 时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。其中整数num的取值有各种各样,不过一般来说,我们的num = 3。
代码实现
1.直接插入排序
先看代码
void Insert_sort(vector<int>& a)
{//从第二个元素开始进行排序,一直到最后一个元素for (int i = 1; i < a.size(); i++){//用end记录需要排序的元素的前一个元素的下标,tmp用来保存当前需要排序的元素int end = i - 1, tmp = a[i];//用while循环对a[i]进行排序while (end >= 0){//end位置的元素大于tmp(也就是a[i])时,把end位置的元素复制到end + 1的位置上,并且end--,继续进行比较if (a[end] > tmp){a[end + 1] = a[end];end--;}//因为我们插入一个新的元素时,它前面的元素都已经是有序的,因此当end位置的元素不大于tmp时,循环结束else break;}//当循环结束时由于end进行一次减一操作,所以该元素所处的正确位置为end + 1a[end + 1] = tmp;}
}
解析:通过注释相信大家基本上已经能够了解代码的意思,接下来我会通过画图的方式再给大家进行更加详细的介绍

通过上面的图相信大家对直接插入排序已经十分了解了。
2.希尔排序
在前面已经为大家详细的介绍希尔排序的过程,下面的代码大家可以参考一下:
void Shell_sort(vector<int>& a)
{//先将元素个数赋值给gap,这样在循环中可以很好的控制gapint gap = a.size();while (gap > 1){gap = gap / 3 + 1;//我们可以不必一组一组的进行排序,而是i走到哪一组就对哪一组的元素进行排序,这样可以节省一层for循环for (int i = gap; i < a.size(); i++){//因为此时的每一组的元素相距为gap,因此我们从gap位置开始枚举,即每一组的第二个元素//此时要找到前一个元素的下标end需要用i - gapint end = i - gap, tmp = a[i];while (end >= 0){if (a[end] > tmp){//与上面同理,我们每组中元素相距gap,因此end + gap才是end位置后的那一个元素位置a[end + gap] = a[end];end-=gap;}else break;}//与上面同理a[end + gap] = tmp;}}
}
注: 上述两种排序的算法博主用的是从第二个元素去找前一个元素,大家也可以反过来,例如在直接插入排序算法中for循环改为 for(int i = 0; i < a.size() - 1; i++) 此时 end = i,tmp = a[i + 1]。根据个人习惯选择即可。
总结
1.时空复杂度
简单分析我们可以得到直接插入排序算法的时间复杂度和空间复杂度
直接插入排序:
时间复杂度:O(N ^ 2)
空间复杂度:O(1)
对于希尔排序来说,对于整数num的取值不同,其时间复杂度也不同,导致很难去计算时间复杂度,因此很多书中给出的希尔排序的时间复杂度都不固定。《数据结构(C语言版)》--- 严蔚敏书中给出的时间复杂度为:

希尔排序:
时间复杂度:O(nlogn ~ n ^ 2)
空间复杂度:O(1)
希尔排序算法是在直接插入排序算法的基础上进行改进而来的,综合来说它的效率肯定是要高于直接插入排序算法的。
2.稳定性
在排序算法中,我们不光要关注算法的时空复杂度,还在看看算法的稳定性,什么是稳定性呢?
稳定性是假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
执行过程中,若遇到和插入元素相等的位置,则将要插人的元素放在该相等元素的后面,因此插入该元素后并未改变原序列的前后顺序。我们认为插入排序是一种稳定的排序方法。但是对于希尔排序来说,因为对数据进行了分组,因此在排序过程中会出现相同的元素不在同一组中,导致其相对位置发生了改变,因此我们说希尔排序是不稳定的。
直接插入排序: 稳定
希尔排序: 不稳定
尾声
若有纰漏或不足之处欢迎大家在评论区留言或者私信,同时也欢迎各位一起探讨学习。感谢您的观看!
相关文章:
【排序算法】——插入排序
目录 前言 简介 基本思想 1.直接插入排序 2.希尔排序 代码实现 1.直接插入排序 2.希尔排序 总结 1.时空复杂度 2.稳定性 尾声 前言 排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列&…...
MySQL的并发控制与MVCC机制深度解析
目录 1. MySQL中的并发问题2. 数据库的隔离级别3. MVCC(多版本并发控制)机制3.1 MVCC的实现原理3.2 Read View详解3.3 当前读与快照读 4. MVCC在不同隔离级别下的工作方式5. MVCC解决幻读问题6. MVCC的优缺点优点:缺点: 7. MVCC在…...
Qt编译MySQL数据库驱动
目录 Qt编译MySQL数据库驱动 测试程序 Qt编译MySQL数据库驱动 (1)先找到MySQL安装路径以及Qt安装路径 C:\Program Files\MySQL\MySQL Server 8.0 D:\qt\5.12.12 (2)在D:\qt\5.12.12\Src\qtbase\src\plugins\sqldrivers\mysql下…...
uniapp地址类 方法
关于点击没反应 manifest.json 检查是否添加了对应的权限 /* 小程序特有相关 */"mp-weixin" : {"appid" : "wxc481f10754f1d9df","setting" : {"urlCheck" : false,"es6" : true,"postcss" : true,&qu…...
使用Idea自带的git功能进行分支合并
文章目录 1.背景描述2.分支切换3.分支合并的具体操作4.将在local环境下,从dev合并到qas分支上的代码,推送到远端 1.背景描述 目前在开发的当前项目有四个分支,master(主分支)、pre(预生产分支)、qas(测试分支)、dev(开发分支); …...
酷盾安全:Edge SCDN边缘安全内容分发网络
在当今数字化迅猛发展的时代,互联网内容分发的高效与安全成为了企业不可忽视的重要课题。为了满足这一需求,酷盾安全推出了创新的Edge Secure Content Delivery Network(Edge Scdn)解决方案,它不仅融合了分布式DDoS防护…...
H5 中 van-popup 的使用以及题目的切换
H5 中 van-popup 的使用以及题目的切换 在移动端开发中,弹窗组件是一个常见的需求。vant 是一个轻量、可靠的移动端 Vue 组件库,其中的 van-popup 组件可以方便地实现弹窗效果。本文将介绍如何使用 van-popup 实现题目详情的弹窗展示,并实现…...
Liinux下VMware Workstation Pro的安装,建议安装最新版本17.61
建议安装最新版本17.61,否则可能有兼容性问题 下载VMware Workstation安装软件 从官网网站下载 https://support.broadcom.com/group/ecx/productdownloads?subfamilyVMwareWorkstationPro 选择所需版本 现在最新版本是17.61,否则可能有兼容性问题…...
WebRTC服务质量(05)- 重传机制(02) NACK判断丢包
WebRTC服务质量(01)- Qos概述 WebRTC服务质量(02)- RTP协议 WebRTC服务质量(03)- RTCP协议 WebRTC服务质量(04)- 重传机制(01) RTX NACK概述 WebRTC服务质量(…...
修改ubuntu apt 源及apt 使用
视频教程:修改ubuntu apt 源和apt 使用方法_哔哩哔哩_bilibili 1 修改apt源 1.1 获取阿里云ubuntu apt 源 https://developer.aliyun.com/mirror/ubuntu?spma2c6h.13651102.0.0.3e221b11mqqLBC 1.2 修改apt 源 vim /etc/apt/sources.list deb https://mirrors.aliyun.com/ub…...
深入解析 `DataFrame.groupby` 和 `agg` 的用法及使用场景
深入解析 DataFrame.groupby 和 agg 的用法及使用场景 1. groupby 的基本用法语法:示例: 2. agg 的基本用法语法:示例: 3. first、sum、lambda 的用法3.1 first示例: 3.2 sum示例: 3.3 lambda示例ÿ…...
MySQL 的锁
MySQL有哪些锁?各种锁的作用与使用场景全局锁表级锁表锁元素锁意向锁AUTO-INC 锁 行级锁记录锁间隙锁临键锁 其他共享锁排他锁乐观锁悲观锁 MySQL有哪些锁? 全局锁表级锁 a. 表锁 b. 元素锁 c. 意向锁 d. AUTO-INC 锁行级锁 a. 记录锁 b. 间隙锁 c. 临键锁 各种锁的作用与使…...
二、使用langchain搭建RAG:金融问答机器人--数据清洗和切片
选择金融领域的专业文档作为源文件 这里选择 《博金大模型挑战赛-金融千问14b数据集》,这个数据集包含若干公司的年报,我们将利用这个年报搭建金融问答机器人。 具体下载地址 这里 git clone https://www.modelscope.cn/datasets/BJQW14B/bs_challenge_…...
【Linux】-- linux 配置用户免密登录本机
比如我们要配置用户 app_tom 免密登录本机(SSH 登录自己机器时无需输入密码),你可以按照以下步骤操作: 步骤 1:切换到 app_tom 用户 首先,确保你已经以 app_tom 用户登录,或者切换到该用户&…...
泷羽sec学习打卡-brupsuite8伪造IP和爬虫审计
声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都 与本人无关,切莫逾越法律红线,否则后果自负 关于brupsuite的那些事儿-Brup-FaskIP 伪造IP配置环境brupsuite导入配置1、扩展中先配置python环境2、安…...
【uniapp蓝牙】基于native.js链接ble和非ble蓝牙
【uniapp蓝牙】基于native.js链接ble和非ble蓝牙 uniapp不是仅支持低功耗蓝牙(基础蓝牙通讯不支持),有些可能需要基础蓝牙。我现在同步我的手机蓝牙列表低功耗,基础蓝牙都支持 /*** author wzj* 通用蓝牙模块封装* 搜索 ble 和非…...
.NET Core 各版本特点、差异及适用场景详解
随着 .NET Core 的不断发展,微软推出了一系列版本来满足不同场景下的开发需求。这些版本随着时间的推移逐渐演变为统一的 .NET 平台(从 .NET 5 开始)。本文将详细说明每个版本的特点、差异以及适用场景,帮助开发者更好地选择和使用…...
Linux中自动检测并定时关闭KDialog程序
自动检测并关闭对话框的程序示例 创建并打开KDialog的脚本自动检测并定时关闭KDialog的脚本 创建并打开KDialog的脚本 #!/bin/bash kdialog --msgbox "demo"自动检测并定时关闭KDialog的脚本 #!/bin/bash# Continuously check for kdialog dialog while true; do# …...
CSS学习记录12
CSS浮动 CSSfloat属性规定元素如何浮动 CSSclear属性规定哪些元素可以在清除的元素旁边以及在哪一侧浮动。 float属性 float属性用于定位和格式化内容,例如让图像向左浮动到容器的文本那里。 float属性可以设置以下值之一: left - 元素浮动到其容器…...
【Java基础面试题016】JavaObject类中有什么主要方法,作用是什么?
equals() 作用:用于比较两个对象是否相等。默认实现比较对象的内存地址,即判断两个引用是否指向同一个对象 使用:通常会重写此方法来比较对象的内容 hashCode() 作用:返回对象的哈希值,用整数表示对象。 使用&…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
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…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
门静脉高压——表现
一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构:由肠系膜上静脉和脾静脉汇合构成,是肝脏血液供应的主要来源。淤血后果:门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血,引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...
