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

目录

前言

简介

基本思想

  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 + 1
        a[end + 1] = tmp;
    }
}

        解析:通过注释相信大家基本上已经能够了解代码的意思,接下来我会通过画图的方式再给大家进行更加详细的介绍

        通过上面的图相信大家对直接插入排序已经十分了解了。

 2.希尔排序

        在前面已经为大家详细的介绍希尔排序的过程,下面的代码大家可以参考一下:

void Shell_sort(vector<int>& a)
{
    //先将元素个数赋值给gap,这样在循环中可以很好的控制gap
    int gap = a.size();
    while (gap > 1)
    {
        gap = gap / 3 + 1;
        //我们可以不必一组一组的进行排序,而是i走到哪一组就对哪一组的元素进行排序,这样可以节省一层for循环
        for (int i = gap; i < a.size(); i++)
        {
            //因为此时的每一组的元素相距为gap,因此我们从gap位置开始枚举,即每一组的第二个元素
            //此时要找到前一个元素的下标end需要用i - gap
            int 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]之前,则称这种排序算法是稳定的;否则称为不稳定的。

        执行过程中,若遇到和插入元素相等的位置,则将要插人的元素放在该相等元素的后面,因此插入该元素后并未改变原序列的前后顺序。我们认为插入排序是一种稳定的排序方法。但是对于希尔排序来说,因为对数据进行了分组,因此在排序过程中会出现相同的元素不在同一组中,导致其相对位置发生了改变,因此我们说希尔排序是不稳定的。

直接插入排序:    稳定

希尔排序:           不稳定

尾声

        若有纰漏或不足之处欢迎大家在评论区留言或者私信,同时也欢迎各位一起探讨学习。感谢您的观看!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL学习之DDL操作

目录 数据库的操作 创建 查看 选择 删除 修改 数据类型 表的创建 表的修改 表的约束 主键 PRIMARY KEY 唯一性约束 UNIQUE 非空约束 NOT NULL 外键约束 约束小结 索引 索引分类 常规索引 主键索引 唯一索引 外键索引 优点 缺点 视图 创建 删除 修改…

四、网络层:数据平面,《计算机网络(自顶向下方法 第7版,James F.Kurose,Keith W.Ross)》

文章目录 零、导论0.1 网络层服务0.2 网络层的关键功能0.3 网络层&#xff1a;数据平面、控制平面0.4 传统方式&#xff1a;每一路由器&#xff08;Per-router&#xff09;控制平面0.5 传统方式&#xff1a;路由和转发的相互作用0.6 SDN方式&#xff1a;逻辑集中的控制平面0.7 …

Java每日一题(1)

给定n个数a1,a2,...an,求它们两两相乘再相加的和。 即&#xff1a;Sa1*a2a1*a3...a1*ana2*a3...an-2*an-1an-2*anan-1*an 第一行输入的包含一个整数n。 第二行输入包含n个整数a1,a2,...an。 样例输入 4 1 3 6 9 样例输出 117 答案 import java.util.Scanner; // 1:无…

(2024.12自用存档)Ubuntu20.04——DynSLAM运行命令

前面忘记记录了&#xff0c;大概记一下后面 看了很多大佬的文章&#xff08;感谢&#xff01;&#xff09;&#xff0c;包括但不限于以下参考文章&#xff1a; Ubuntu16.04编译dynslam总结-CSDN博客 ubuntu14.04 CUDA8.0 DynSLAM编译与运行-CSDN博客 【视觉SLAM十四讲】Pa…

【阅读笔记】Android AMS forcestop停止应用

根据这篇文章作的笔记 基于Android 12的force-stop流程分析_android forcestop-CSDN博客 在AMS中&#xff0c;停止指定的应用是一个常用的功能&#xff0c;在代码里可以看到 Override 6806 public void forceStopPackage(final String packageName, int userId) { 6807 …

uniapp连接蓝牙操作(蓝牙设备地锁)

介绍&#xff1a; 本文采用uni-app框架来创建一个简单的用户界面&#xff0c;用于搜索、连接和发送命令给蓝牙设备。 1.打开蓝牙适配器 function openBluetooth() {uni.openBluetoothAdapter({success() {uni.offBluetoothDeviceFound();// 监听新设备发现事件uni.onBlueto…

《拉依达的嵌入式\驱动面试宝典》—前言目录篇

《拉依达的嵌入式\驱动面试宝典》—前言&目录篇 你好&#xff0c;我是拉依达。 感谢所有阅读关注我的同学支持&#xff0c;目前博客累计阅读 27w&#xff0c;关注1.5w人。其中博客《最全Linux驱动开发全流程详细解析&#xff08;持续更新&#xff09;-CSDN博客》已经是 Lin…

【博弈模型】古诺模型、stackelberg博弈模型、伯特兰德模型、价格领导模型

博弈模型 1、古诺模型&#xff08;cournot&#xff09;&#xff08;1&#xff09;假设&#xff08;2&#xff09;行为分析&#xff08;3&#xff09;经济后果&#xff08;4&#xff09;例题 2、stackelberg博弈模型&#xff08;产量领导模型&#xff09;&#xff08;1&#xff…

如何利用Python爬虫获得1688商品详情

在这个信息爆炸的时代&#xff0c;数据就像是一块块美味的奶酪&#xff0c;而爬虫就是我们手中的瑞士军刀。今天&#xff0c;我要带你一起潜入1688这个巨大的奶酪洞穴&#xff0c;用Python爬虫捞起那些香气四溢的商品详情。别担心&#xff0c;我们的工具箱里有各种各样的工具&a…

blender 制作莫比乌斯带

创建 Curve -> Cycle 在 Edit 模式下&#xff0c;选择&#xff1a; 选中两个点&#xff0c;按 delete 删除 Segment 如下选中&#xff1a; 选中最上面的点&#xff0c;然后按 E 将它拖到右边的点上。 按 R 旋转 90 度。 依次调整参数&#xff1a; 回到 Object 模式下&#x…

《云原生安全攻防》-- K8s安全框架:认证、鉴权与准入控制

从本节课程开始&#xff0c;我们将来介绍K8s安全框架&#xff0c;这是保障K8s集群安全比较关键的安全机制。接下来&#xff0c;让我们一起来探索K8s安全框架的运行机制。 在这个课程中&#xff0c;我们将学习以下内容&#xff1a; K8s安全框架&#xff1a;由认证、鉴权和准入控…

研华运动控制卡 (如PCI1245)单轴编辑路

问题描述: 单轴如何编辑路径&#xff1f; n 问题分析及处理办法– 步骤 在utility软件中&#xff0c;编辑路径和运行路径只能在多轴运动这个界面&#xff0c;而且&#xff0c;使用函数来加载路径Acm_GpLoadPath&#xff0c;也是需要多个轴 ​ 如果只运行一个轴&#xff0c;需…

LM芯片学习

1、LM7805稳压器 https://zhuanlan.zhihu.com/p/626577102?utm_campaignshareopn&utm_mediumsocial&utm_psn1852815231102873600&utm_sourcewechat_sessionhttps://zhuanlan.zhihu.com/p/626577102?utm_campaignshareopn&utm_mediumsocial&utm_psn18528…

ChromeOS 131 版本更新

ChromeOS 131 版本更新 1. ChromeOS Flex 自动注册 在 ChromeOS 131 中&#xff0c;ChromeOS Flex 的自动注册功能现已允许大规模部署 ChromeOS Flex 设备。与 ChromeOS 零接触注册类似&#xff0c;自动注册将通过组织管理员创建的注册令牌嵌入到 ChromeOS Flex 镜像中。这将…

electron打包linux环境

注意:新版的electron已经不支持在win上直接打包Linux的环境了,服务会卡住,会一直生成文件占用磁盘(我发现的时候占了我100G&#xff0c;而且文件夹很深&#xff0c;找了java代码while循环&#xff0c;好不容易删除的o(╥﹏╥)o) electron有一个专门打包的docker镜像&#xff0c…

【SAP FICO】物料分类账详述

系列文章目录 文章目录 系列文章目录前言一、必备基础1、标准价和移动平均价2、概念3、意义4、功能 二、工作原理三、差异的种类与来源1、采用S价可能产生的差异2、单层价格差异和多层价格差异 四、后台配置总结 前言 业务背景&#xff1a;中国会计准则规定&#xff0c;对存货…

电脑文档损坏:原因剖析和修复方法

在使用电脑的过程中&#xff0c;许多用户可能会遇到文档突然提示损坏、无法打开的情况。这种情况的发生往往让人感到困惑&#xff0c;特别是当并未进行任何明显错误操作时。以下是一些常见的原因以及应对方法。 一、文档损坏的常见原因 1、非人为的异常操作&#xff1a; 在编…

使用国内镜像网站在线下载安装Qt(解决官网慢的问题)——Qt

国内镜像网站 中国科学技术大学&#xff1a;http://mirrors.ustc.edu.cn/qtproject/清华大学&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/qt/北京理工大学&#xff1a;http://mirror.bit.edu.cn/qtproject/ 南京大学&#xff1a;https://mirror.nju.edu.cn/qt腾讯镜像&…

活动预告|云原生创新论坛:知乎携手 AutoMQ、OceanBase、快猫星云的实践分享

近年来&#xff0c;云原生技术迅猛发展&#xff0c;成为企业数字化转型的关键动力&#xff0c;云原生不仅极大地提升了系统的灵活性和可扩展性&#xff0c;还为企业带来了前所未有的创新机遇。 12 月 28 日 知乎携手 AutoMQ、OceanBase 和快猫星云推出“云原生创新论坛”主题的…

02-2.python入门语法一变量与数据类型2

四、Python 整数数据类型 &#xff08;一&#xff09;整数的表示方式 1. 十进制表示 十进制是我们在日常生活中最常用的数字表示形式&#xff0c;由 0 到 9 这十个数字排列组合而成。 2. 二进制表示 二进制数由 0 和 1 这两个数字组成&#xff0c;在 Python 中&#xff0c;…