【排序算法】——插入排序
目录
前言
简介
基本思想
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) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列&…...
Vue todoList小项目记录
最初代码 简单搭一个vue2的小项目 App.vue <template><div id"app"><!-- 容器 --><div class"todo-container"><div class"todo-wrap"><!-- 头部 --><MyHeader :addTodo"addTodo"></…...
SQL题目笔记
一、根据需求创建表(设计合理的数据类型、长度)...
电脑开机提示error loading operating system怎么修复?
前一天电脑还能正常运行,但今天启动时却显示“Error loading operating system”(加载操作系统错误)。我已经仔细检查了硬盘、接线、内存、CPU和电源,确认这些硬件都没有问题。硬盘在其他电脑上可以正常使用,说明不是硬…...
Nginx 在不同操作系统下的安装指南
Nginx 在不同操作系统下的安装指南 一、Linux 系统下 Nginx 的安装 (一)基于 Ubuntu 系统 更新软件包列表 打开终端,首先执行sudo apt-get update命令。这一步是为了确保系统的软件包列表是最新的,能够获取到最新版本的 Nginx 及…...
景联文科技入选中国信通院发布的“人工智能数据标注产业图谱”
近日,由中国信息通信研究院、中国人工智能产业发展联盟牵头,联合中国电信集团、沈阳市数据局、保定高新区等70多家单位编制完成并发布《人工智能数据标注产业图谱》。景联文科技作为人工智能产业关键环节的代表企业,入选图谱中技术服务板块。…...
Nginx - 负载均衡及其配置(Balance)
一、概述 定义:在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载目标:最佳化资源使用、最大化吞吐率、最小化响应时间、避免过载功能:使用多台服务器提供单一服务(服务器农场&am…...
MySQL存储引擎-存储结构
Innodb存储结构 Buffer Pool(缓冲池):BP以Page页为单位,页默认大小16K,BP的底层采用链表数据结构管理Page。在InnoDB访问表记录和索引时会在Page页中缓存,以后使用可以减少磁盘IO操作,提升效率。 ○ Page根据状态可以分…...
数据资产入表 解锁智慧城市新潜力
在21世纪的科技浪潮中,智慧城市以信息技术为核心,以数据为血液,通过智能化、精细化的管理,让城市变得更加智慧、更加宜居。而数据资产入表,正是这一变革中的关键一环,它不仅推动了科技的进步,更…...
按类别调整目标检测标注框的写入顺序以优化人工审核效率
引言 在目标检测数据标注审核过程中,我们常常会遇到以下情况:某些小目标的检测框嵌套在大目标检测框内,而在模型进行预标注后,这些小目标的框可能被写入到了大目标框的下层。在人工审核阶段,标注审核人员需要手动移动…...
深入理解YOLO系列目标检测头的设定方式
目录 YOLOv1的检测头结构 1. 网络结构概述 2. 结构细节 3. 优缺点 YOLOv2的检测头结构 1. 网络结构概述 2. 结构细节 3. 优缺点 YOLOv3的检测头结构 1. 网络结构概述 2. 结构细节 3. 优缺点 总结:YOLO 系列检测头的结构演变 YOLOv1的检测头结构 1. 网络…...
智慧农业物联网解决方案:道品科技水肥一体化
在当今科技飞速发展的时代,农业也迎来了一场深刻的变革。智慧农业物联网解决方案中的水肥一体化技术,正逐渐成为现代农业发展的重要助推器。它不仅提高了农业生产效率,还实现了精准施肥和灌溉,为农业可持续发展带来了新的机遇。 …...
单片机上电后程序不运行怎么排查问题?
1.电源检查。使用电压表测量单片机的电源电压是否正常,确保电压在规定的范围内,如常见的5V。 2.复位检查。检查复位引脚的电压是否正常,在单片机接通电源时,复位引脚通常会有一个高电平,按下复位按钮时,复位…...
OceanBase 数据库分布式与集中式 能力
OceanBase分布式数据库与集中式数据库的差异 分布式数据库能解决金融行业最有挑战的高并发低延迟的核心交易系统的稳定性、扩展性、高性能问题。OB之所以一直强调分布式是说它具备很强的数据处理能力,当然从OB4.0开始也支持集中式了。 在实际业务场景中20%是分布式…...
C#多线程
C#中的多线程编程是开发高效并发应用程序的关键技术之一,它允许程序同时执行多个任务,从而提升应用程序的响应速度和性能。为了更好地理解C#中的多线程使用和定义,我们可以从以下几个方面来探讨:线程的基本概念、创建线程的方法、…...
Apache HTTP 服务器深度性能优化
引言 在前几篇文章中,我们讨论了基础和高级性能优化策略。现在,我们将深入探讨一些具体的优化实践,帮助您实现更精细的控制,并确保Apache服务器在各种复杂环境中都能保持最佳性能。 1. 细粒度的Apache配置调整 1.1 MPM参数微调…...
芯片级IO (Pad) Ring IP Checklist
SoC top顶层数字后端实现都会涉及到IO Ring (PAD Ring)的设计。这里面包括VDD IO,VDDIO IO, Signal IO, Corner IO,Filler IO,IO power cut cell等等。 数字后端零基础入门系列 | Innovus零基础LAB学习Day2 数字IC后端实现TOP F…...
无界wujie网址
文档网址:微前端是什么 | 无界 demo:https://wujie-micro.github.io/demo-main-vue/react17...
vulnhub靶场【DriftingBlues】之6
前言 靶机:DriftingBlues-6,IP地址192.168.1.63,因为重装靶机后期为192.168.1.64 攻击:kali,IP地址192.168.1.16 都采用虚拟机,网卡为桥接模式 主机发现 使用arp-scan -l或netdiscover -r 192.168.1.1…...
心情追忆- Nginx + OpenResty 构建高可用网关
之前,我独自一人开发了一个名为“心情追忆”的小程序,旨在帮助用户记录日常的心情变化及重要时刻。我从项目的构思、设计、前端(小程序)开发、后端搭建到最终部署。经过一个月的努力,通过群聊分享等方式,用…...
太速科技-527-基于3U VPX XCZU15EG+TMS320C6678的信号处理板
基于3U VPX XCZU15EGTMS320C6678的信号处理板 一、板卡概述 本板卡系我司自主研发的基于3U VPX风冷、导冷架构的信号处理板,适用于高速图像处理等。芯片采用工业级设计。 板卡采用标准3U VPX架构,板上集成一片Xilinx公司ZynqUltraScale系列F…...
Vue3源码笔记阅读1——Ref响应式原理
本专栏主要用于记录自己的阅读源码的过程,希望能够加深自己学习印象,也欢迎读者可以帮忙完善。接下来每一篇都会从定义、运用两个层面来进行解析 定义 运用 例子:模板中访问ref(1) <template><div>{{str}}</div> </template> <script> impo…...
多音轨视频使用FFmpeg删除不要音轨方法
近期给孩子找宫崎骏动画,但是有很多是多音轨视频但是默认的都是日语,电视上看没办法所以只能下载后删除音轨文件只保留中文。 方法分两步,先安装FFmpeg在转文件即可。 第一步FFmpeg安装 FFmpeg是一个开源项目,包含了处理视频的…...
AtomGit 开源生态应用开发赛报名开始啦
目录 1、赛项背景2、赛项信息3、报名链接4、赛题一:开发者原创声明(DCO)应用开发赛题要求目标核心功能 5、赛题二:基于 OpenHarmony 的开源社区应用开发简介赛题要求 6、参赛作品提交初赛阶段决赛阶段 7、参赛作品提交方式 1、赛项…...
使用 NVIDIA DALI 计算视频的光流
引言 光流(Optical Flow)是计算机视觉中的一种技术,主要用于估计视频中连续帧之间的运动信息。它通过分析像素在时间维度上的移动来预测运动场,广泛应用于目标跟踪、动作识别、视频稳定等领域。 光流的计算传统上依赖 CPU 或 GP…...
C语言学习day23:WriteProcessMemory函数/游戏内存数据修改工具开发
简言: 上一章我们说了获取应用进程的某数据(data),这一章我们就说说修改内存地址的数据。想要修改内存,那么就需要我们另一个WinAPI函数:WriteProcessMemory()函数。 WriteProcessMemory()函数 函数原型…...
利用 html_table 函数轻松获取网页中的表格数据
背景/引言 在数据爬取的过程中,网页表格数据往往是研究人员和开发者的重要目标之一。无论是统计分析、商业调研还是信息整理,表格数据的结构化特性都使其具有较高的利用价值。然而,如何快速、准确地从网页中提取表格数据始终是爬虫技术的一个…...
Postman接口测试:全局变量/接口关联/加密/解密
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 全局变量和环境变量 全局变量:在postman全局生效的变量,全局唯一 环境变量:在特定环境下生效的变量,本环境内唯一 …...
手机银行模拟器,一款高仿真银行app的模拟器,可以修改姓名 卡号 余额 做转账记录 做流水
📱手机银行模拟器让你自由定制你的金融生活。无论是流水账单、金额,还是个人信息,一切都可以按照你的意愿来模拟修改,让你体验模拟器带来的快乐! 链接:https://pan.quark.cn/s/c2f614f3447f 提取码&#…...
HT7183:16V, 4.5A的DC-DC升压转换器,常用在数码相机里
HT7183描述: HT7183是一款高功率异步升压转换器,集成120mΩ功率开关管,为便携式系统提供高效的小尺寸解决方案。具有2.6V至5.5V输入电压范围,可为各类不同供电的应用提供支持。该器件具备3A开关电流能力,并且能够提供高…...
Cobalt Strike 4.8 用户指南-第十四节 Aggressor 脚本
14.1、什么是Aggressor脚本 Aggressor Script 是Cobalt Strike 3.0版及更高版本中内置的脚本语言。Aggressor 脚本允许你修改和扩展 Cobalt Strike 客户端。 历史 Aggressor Script 是 Armitage 中开源脚本引擎Cortana的精神继承者。Cortana 是通过与 DARPA 的网络快速跟踪计…...
【Qt】QWidget中的常见属性及其功能(二)
目录 六、windowOpacity 例子: 七、cursor 例子: 八、font 九、toolTip 例子: 十、focusPolicy 例子: 十一、styleSheet 计算机中的颜色表示 例子: 六、windowOpacity opacity是不透明度的意思。 用于设…...
对象的克隆 单例模式
1) 如何实现对象的克隆? 1、为什么需要实现对象的克隆? 在某些情况下,需要创建一个与现有对象完全相同的副本,这就是对象克隆。 例如,在需要对对象进行备份、在不同的上下文中使用相同的类型的对象或者实现某些设计…...
预处理内容
预处理是干什么的呢? 分为三点: 1.宏替换 2.头文件导入 3.删除注释 #ifdef #include <iostream> // 定义一个宏,表示当前处于调试模式,在实际调试时可以定义这个宏,发布时取消定义#define DEBUG MODE int ma…...
Docker笔记
1 安装docker b11et3un53m.feishu.cn/wiki/Rfocw7ctXij2RBkShcucLZbrn2d 项目的资料地址(飞书) 当使用docker pull +名字 拉取镜像时报 Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for co…...
条件随机场(CRF)详解:原理、算法与实现(深入浅出)
目录 1. 引言2. 什么是条件随机场?2.1 直观理解2.2 形式化定义 3. CRF的核心要素3.1 特征函数3.2 参数学习 4. 实战案例:命名实体识别5. CRF vs HMM6. CRF的优化与改进6.1 特征选择6.2 正则化 7. 总结与展望参考资料 1. 引言 条件随机场(Conditional Ra…...
C++类与对象学习笔记(一)
https://www.bilibili.com/video/BV1jm4y1w7pa?spm_id_from333.788.player.switch&vd_sourcee8984989cddeb3ef7b7e9fd89098dbe8&p6 🚩🚩🚩来自b站“码农论坛”的视频“类与对象”做的笔记🚩🚩Ὢ…...
wrk如何测试post请求
wrk git地址 https://github.com/wg/wrk wrk 默认是针对 GET 请求的,但它也可以通过添加自定义的 HTTP 请求体和 头部信息来进行 POST 请求的压测。以下是详细的步骤: wrk -t4 -c100 -d30s -s post.lua http://example.com-t4:使用 4 个线…...
rust使用log与env_logger两个crate实现同时向控制台和文件输出日志。并在隔日自动创建新日志文件。
还是老习惯,不用太多的废话。直接上代码。 不过我之说一句话,这块需要自定义一个输出的Target来实现这个功能。 log = { version="0.4.22", default-features = false } env_logger = "0.11.5"pub(crate) fn setup_log_env(log_level: LevelFilter) {...
异步将用户信息存入 Redis 缓存
主要是为了解决Redis的缓存问题,异步将用户信息存入Redis缓存 首先我们需要引入一部线性池 核心概念 异步执行: 异步执行是指任务提交后不会立即等待其完成,而是立即返回并继续执行其他任务。任务将在后台执行,执行结果可以通过…...
WebRTC服务质量(05)- 重传机制(02) NACK判断丢包
WebRTC服务质量(01)- Qos概述 WebRTC服务质量(02)- RTP协议 WebRTC服务质量(03)- RTCP协议 WebRTC服务质量(04)- 重传机制(01) RTX NACK概述 WebRTC服务质量(…...
MySQL 存储过程与函数:增强数据库功能
一、MySQL 存储过程与函数概述 (一)存储过程的定义与特点 存储过程是一组预编译的 SQL 语句集合,它们被存储在数据库中,可根据需要被重复调用。例如,在一个电商系统中,经常需要查询某个时间段内的订单数据…...
丹摩|丹摩助力selenium实现大麦网抢票
丹摩|丹摩助力selenium实现大麦网抢票 声明:非广告,为用户体验 1.引言 在人工智能飞速发展的今天,丹摩智算平台(DAMODEL)以其卓越的AI算力服务脱颖而出,为开发者提供了一个简化AI开发流程的强…...
springcloud-gateway获取应用响应信息乱码
客户端通过springcloud gateway跳转访问tongweb上的应用,接口响应信息乱码。使用postman直接访问tongweb上的应用,响应信息显示正常。 用户gateway中自定义了实现GlobalFilter的Filter类,在该类中获取了上游应用接口的响应信息,直…...
Scala项目(一)
1,创建dao,models,service,ui等软件包 2,在各软件包下创建scala类 软件包dao里的代码 package org.app package daoimport models.BookModelimport scala.collection.mutable.ListBuffer//图书,数据操作…...
node(2) - npm run 原理
1. npm run 执行原理 npm run 命令的原理是执行 package.json 文件中定义的脚本。当你在命令行中运行 npm run 时,npm 会查找 package.json 文件中的 scripts 字段,然后执行对应的脚本命令。 2. 示例 2.1 以 dev:weapp 为例 运行 npm run dev:weapp 命令;npm 会查找 packa…...
概率论得学习和整理24:EXCEL的各种图形,统计图形
目录 0 EXCEL的各种图形,统计图形 1 统计图形 / 直方图 / 其实叫 频度图 hist最合适(用原始数据直接作图) 1.1 什么是频度图 1.2 如何创建频度图,一般是只选中1列数据(1个数组) 1.3 如何修改频度图的宽度 1.4 hist图的一个特…...
【zlm】 webrtc源码讲解三(总结)
目录 setsdp onwrite 编辑 play 参考 setsdp onwrite play 参考 【zlm】 webrtc源码讲解_zlm webrtc-CSDN博客 【zlm】 webrtc源码讲解(二)_webrtc 源码-CSDN博客...
YashanDB共享集群产品能力观测:细节足见功底
本文基于前泽塔数科研发总监-王若楠2024年11月在“2024年国产数据库创新生态大会”-“根”技术专场的演讲整理形成,主要对崖山共享集群YAC的架构、功能、高可用性、性能四大方面进行全面测试,并分享了测试环境和测试结论。 年初,基于某些商业…...
游戏引擎学习第50天
仓库: https://gitee.com/mrxiao_com/2d_game Minkowski 这个算法有点懵逼 回顾 基本上,现在我们所处的阶段是,回顾最初的代码,我们正在讨论我们希望在引擎中实现的所有功能。我们正在做的版本是初步的、粗略的版本,涵盖我们认…...