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

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

目录

前言

简介

基本思想

  1.直接插入排序

 2.希尔排序

代码实现

 1.直接插入排序

 2.希尔排序

总结

1.时空复杂度

2.稳定性

尾声


前言

        排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列。所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作

        排序算法,就是如何使得记录按照要求排列的方法。排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面。一个优秀的算法可以节省大量的资源。

简介

        所谓排序算法,即通过特定的算法因式将一组或多组数据按照既定模式进行重新排序。这种新序列遵循着一定的规则,体现出一定的规律,因此,经处理后的数据便于筛选和计算,大大提高了计算效率。对于一个排序算法的优劣,我们需要从它的时间复杂度、空间复杂度和稳定性三个方面来考虑。什么叫稳定性呢?即当两个相同的元素同时出现于某个序列之中,则经过一定的排序算法之后,两者在排序前后的相对位置不发生变化。换言之,即便是两个完全相同的元素,它们在排序过程中也是各有区别的。

        本篇文章讲述的是排序算法中的插入排序,其中包含了两种排序算法,分别是直接插入排序希尔排序,下面将会一一为大家详细介绍。(用升序进行讲解)

        插入排序算法是基于某序列已经有序排列的情况下,通过一次插入一个元素的方式按照原有排序方式增加元素。这种比较是从该有序序列的最末端开始执行,即要插入序列中的元素最先和有序序列中最大的元素比较,若其大于该最大元素,则可直接插入最大元素的后面即可,否则再向前一位比较查找直至找到应该插入的位置为止。

基本思想

        插入排序的基本思想是,每次将1个待排序的记录按其关键字大小插入到前面已经排好序的序列中,寻找最适当的位置,直至全部记录插入完毕。                                                                       

  1.直接插入排序

        下面我们首先来看一看直接插入算法的动图演示:

        看了上图之后,我们可以得知,直接插入排序是在一个给定的数组中,我们从第二个元素开始,与之前的元素一一进行比较:

        · 若是该位置的元素小于前一个元素,那么就将该位置元素与更前一位的元素再次进行比较,直到前面没有元素,那么此时该元素就放在数组的首位。

        · 若是该位置的元素大于或者等于前一个元素,那么就把该位置的元素放到前一个元素的后面(具体的方式在下面的代码实现中进行讲解)。

        这就是直接插入排序的具体思路,有了它我们便可以写出我们的直接插入排序算法。 

 2.希尔排序

        当数组中的元素越接近有序时,直接插入排序算法的时间效率越高;但是当数组中的元素越不接近有序,特别是倒序时,此时要使元素正序排列,使用直接插入算法的时间效率就非常低了,那我们能不能对直接插入算法进行一些优化呢?

        答案是可以的。既然我们说当元素越有序时的时间效率越高,那我们可以把元素先分为若干份,先将这些部分使用直接插入算法变得有序后再去整体进行直接插入排序算法,从而达到目的,这就是希尔排序。

        希尔排序法又称缩小增量法。希尔排序算法的基本思想是:先选定一个整数,记为num,用num计算出一个距离gap = n / num + 1n为元素总数,把待排序元素分成各组,所有的距离相等的记录分在同一组内,并对每⼀组内的元素进行排序,然后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) 是计算机程序设计中的一种重要操作&#xff0c;它的功能是将一个数据元素&#xff08;或记录&#xff09;的任意序列&…...

MySQL的并发控制与MVCC机制深度解析

目录 1. MySQL中的并发问题2. 数据库的隔离级别3. MVCC&#xff08;多版本并发控制&#xff09;机制3.1 MVCC的实现原理3.2 Read View详解3.3 当前读与快照读 4. MVCC在不同隔离级别下的工作方式5. MVCC解决幻读问题6. MVCC的优缺点优点&#xff1a;缺点&#xff1a; 7. MVCC在…...

Qt编译MySQL数据库驱动

目录 Qt编译MySQL数据库驱动 测试程序 Qt编译MySQL数据库驱动 &#xff08;1&#xff09;先找到MySQL安装路径以及Qt安装路径 C:\Program Files\MySQL\MySQL Server 8.0 D:\qt\5.12.12 &#xff08;2&#xff09;在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环境下&#xff0c;从dev合并到qas分支上的代码&#xff0c;推送到远端 1.背景描述 目前在开发的当前项目有四个分支&#xff0c;master(主分支)、pre(预生产分支)、qas(测试分支)、dev(开发分支)&#xff1b; …...

酷盾安全:Edge SCDN边缘安全内容分发网络

在当今数字化迅猛发展的时代&#xff0c;互联网内容分发的高效与安全成为了企业不可忽视的重要课题。为了满足这一需求&#xff0c;酷盾安全推出了创新的Edge Secure Content Delivery Network&#xff08;Edge Scdn&#xff09;解决方案&#xff0c;它不仅融合了分布式DDoS防护…...

H5 中 van-popup 的使用以及题目的切换

H5 中 van-popup 的使用以及题目的切换 在移动端开发中&#xff0c;弹窗组件是一个常见的需求。vant 是一个轻量、可靠的移动端 Vue 组件库&#xff0c;其中的 van-popup 组件可以方便地实现弹窗效果。本文将介绍如何使用 van-popup 实现题目详情的弹窗展示&#xff0c;并实现…...

Liinux下VMware Workstation Pro的安装,建议安装最新版本17.61

建议安装最新版本17.61&#xff0c;否则可能有兼容性问题 下载VMware Workstation安装软件 从官网网站下载 https://support.broadcom.com/group/ecx/productdownloads?subfamilyVMwareWorkstationPro 选择所需版本 现在最新版本是17.61&#xff0c;否则可能有兼容性问题…...

WebRTC服务质量(05)- 重传机制(02) NACK判断丢包

WebRTC服务质量&#xff08;01&#xff09;- Qos概述 WebRTC服务质量&#xff08;02&#xff09;- RTP协议 WebRTC服务质量&#xff08;03&#xff09;- RTCP协议 WebRTC服务质量&#xff08;04&#xff09;- 重传机制&#xff08;01) RTX NACK概述 WebRTC服务质量&#xff08;…...

修改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 的基本用法语法&#xff1a;示例&#xff1a; 2. agg 的基本用法语法&#xff1a;示例&#xff1a; 3. first、sum、lambda 的用法3.1 first示例&#xff1a; 3.2 sum示例&#xff1a; 3.3 lambda示例&#xff…...

MySQL 的锁

MySQL有哪些锁?各种锁的作用与使用场景全局锁表级锁表锁元素锁意向锁AUTO-INC 锁 行级锁记录锁间隙锁临键锁 其他共享锁排他锁乐观锁悲观锁 MySQL有哪些锁? 全局锁表级锁 a. 表锁 b. 元素锁 c. 意向锁 d. AUTO-INC 锁行级锁 a. 记录锁 b. 间隙锁 c. 临键锁 各种锁的作用与使…...

二、使用langchain搭建RAG:金融问答机器人--数据清洗和切片

选择金融领域的专业文档作为源文件 这里选择 《博金大模型挑战赛-金融千问14b数据集》&#xff0c;这个数据集包含若干公司的年报&#xff0c;我们将利用这个年报搭建金融问答机器人。 具体下载地址 这里 git clone https://www.modelscope.cn/datasets/BJQW14B/bs_challenge_…...

【Linux】-- linux 配置用户免密登录本机

比如我们要配置用户 app_tom 免密登录本机&#xff08;SSH 登录自己机器时无需输入密码&#xff09;&#xff0c;你可以按照以下步骤操作&#xff1a; 步骤 1&#xff1a;切换到 app_tom 用户 首先&#xff0c;确保你已经以 app_tom 用户登录&#xff0c;或者切换到该用户&…...

泷羽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不是仅支持低功耗蓝牙&#xff08;基础蓝牙通讯不支持&#xff09;&#xff0c;有些可能需要基础蓝牙。我现在同步我的手机蓝牙列表低功耗&#xff0c;基础蓝牙都支持 /*** author wzj* 通用蓝牙模块封装* 搜索 ble 和非…...

.NET Core 各版本特点、差异及适用场景详解

随着 .NET Core 的不断发展&#xff0c;微软推出了一系列版本来满足不同场景下的开发需求。这些版本随着时间的推移逐渐演变为统一的 .NET 平台&#xff08;从 .NET 5 开始&#xff09;。本文将详细说明每个版本的特点、差异以及适用场景&#xff0c;帮助开发者更好地选择和使用…...

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属性用于定位和格式化内容&#xff0c;例如让图像向左浮动到容器的文本那里。 float属性可以设置以下值之一&#xff1a; left - 元素浮动到其容器…...

【Java基础面试题016】JavaObject类中有什么主要方法,作用是什么?

equals() 作用&#xff1a;用于比较两个对象是否相等。默认实现比较对象的内存地址&#xff0c;即判断两个引用是否指向同一个对象 使用&#xff1a;通常会重写此方法来比较对象的内容 hashCode() 作用&#xff1a;返回对象的哈希值&#xff0c;用整数表示对象。 使用&…...

实践环境-docker安装mysql8.0.40步骤

一、docker安装mysql 8.0.40版本 1、检索镜像版本 docker search mysql:8.0.40 NAME DESCRIPTION STARS OFFICIAL mysql MySQL is a widely used, open-source relation… …...

边缘智能创新应用大赛获奖作品系列一:智能边缘计算✖软硬件一体化,开启全场景效能革命新征程

边缘智能技术快速迭代&#xff0c;并与行业深度融合。它正重塑产业格局&#xff0c;催生新产品、新体验&#xff0c;带动终端需求增长。为促进边缘智能技术的进步与发展&#xff0c;拓展开发者的思路与能力&#xff0c;挖掘边缘智能应用的创新与潜能&#xff0c;高通技术公司联…...

决策树的生成与剪枝

决策树的生成与剪枝 决策树的生成生成决策树的过程决策树的生成算法 决策树的剪枝决策树的损失函数决策树的剪枝算法 代码 决策树的生成 生成决策树的过程 为了方便分析描述&#xff0c;我们对上节课中的训练样本进行编号&#xff0c;每个样本加一个ID值&#xff0c;如图所示…...

蓝桥杯算法训练 黑色星期五

题目描述 有些西方人比较迷信&#xff0c;如果某个月的13号正好是星期五&#xff0c;他们就会觉得不太吉利&#xff0c;用古人的说法&#xff0c;就是“诸事不宜”。请你编写一个程序&#xff0c;统计出在某个特定的年份中&#xff0c;出现了多少次既是13号又是星期五的情形&am…...

MySQL存储引擎-存储结构

Innodb存储结构 Buffer Pool(缓冲池)&#xff1a;BP以Page页为单位&#xff0c;页默认大小16K&#xff0c;BP的底层采用链表数据结构管理Page。在InnoDB访问表记录和索引时会在Page页中缓存&#xff0c;以后使用可以减少磁盘IO操作&#xff0c;提升效率。 ○ Page根据状态可以分…...

理解torch函数bmm

基本信息 功能描述 torch.bmm 是 PyTorch 中的一个函数&#xff0c;用于执行批量矩阵乘法&#xff08;Batch Matrix Multiplication&#xff09;。它适用于处理一批矩阵的乘法操作&#xff0c;特别适合于深度学习任务中的场景&#xff0c;比如卷积神经网络中的某些层。 参数…...

2024 年的科技趋势

2024 年在科技领域有着诸多重大进展与突破。从人工智能、量子计算到基因组医学、可再生能源以及新兴技术重塑了众多行业。随着元宇宙等趋势的兴起以及太空探索取得的进步&#xff0c;未来在接下来的岁月里有望继续取得进展与突破。让我们来探讨一下定义 2024 年的一些关键趋势&…...

win服务器的架设、windows server 2012 R2 系统的下载与安装使用

文章目录 windows server 2012 R2 系统的下载与安装使用1 windows server 2012 的下载2 打开 VMware 虚拟机软件&#xff08;1&#xff09;新建虚拟机&#xff08;2&#xff09;设置虚拟机&#xff08;3&#xff09;打开虚拟机 windows server 2012&#xff08;4&#xff09;进…...

leetcode45.跳跃游戏II

标签&#xff1a;动态规划 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处:返回到达 nums[n - 1] 的最小跳跃次数。…...

边缘智能创新应用大赛获奖作品系列三:边缘智能强力驱动,机器人天团花式整活赋能千行百业

边缘智能技术快速迭代&#xff0c;并与行业深度融合。它正重塑产业格局&#xff0c;催生新产品、新体验&#xff0c;带动终端需求增长。为促进边缘智能技术的进步与发展&#xff0c;拓展开发者的思路与能力&#xff0c;挖掘边缘智能应用的创新与潜能&#xff0c;高通技术公司联…...