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

【初阶数据结构】排序——插入排序

目录

  • 前言
  • 直接插入排序
  • 希尔排序

请添加图片描述

前言

  排序:所谓排序就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作排序算法,就是如何使得记录按照要求排列的方法。
  例如:买东西时会根据销量或价格排序综合比对,又如玩扑克牌时会将手中的牌按自己喜欢的顺序进行排序等待,排序在生活中很常见,常见的排序算法又有以下几种:
在这里插入图片描述
下面我们就来讲讲插入排序。

直接插入排序

  直接插入排序是一种简单的插入排序法。

基本思想待排序的数据逐个插入到一个已经排好序的序列中,使其同样为有序序列,直到所有的记录插完为止,得到一个新的有序序列。

  实际上我们玩扑克牌时就会用到此思想:先拿起一张放手上,拿第二张时会和第一张比较大小,以此来插入,拿第三张时又会对比前两张的大小,找到合适的位置插入……
我们可以简单来看一下排序过程:
在这里插入图片描述
过程分析(以升序为例):

  • 第一个数看成是一个有序序列,从第二个元素开始逐个插入到这有序序列中。
  • 当插入第i(i>=1)个元素时,前面的a[0]……a[i-1]都已经排好序
  • 此时将a[i]的大小与按照从右至左的顺序依次进行比较,找到第一个比它的数字,记为a[end]
  • a[end]后面的数都往后挪一位,a[end+1]处插入那个元素
    在这里插入图片描述
    具体代码如下:
//思想就像理扑克牌一样,把第一项当成有序,后面依次插入
void InsertSort(int* a, int n)//插入排序
{for (int i = 0; i < n - 1; i++){int end = i;int tmp = a[end + 1];//需要插入排序的值while (end >= 0){if (a[end] > tmp)//一直找到比tmp小的值{a[end + 1] = a[end];end--;}elsebreak;}//若未找到跳出循环证明tmp最小,此时end=-1,tmp插在end+1也就是最前面a[end + 1] = tmp;}}

直接插入排序的特性总结:

  1. 元素集合越接近有序直接插入排序算法的时间效率越高
  2. 时间复杂度:O(N^2^)
    按照最坏情况来看是逆序时,第2个数字插入前面数字往后挪1位,第3个数字插入时前面数字要往后挪两位,以此类推,到第n个数字插入时则前面的数字要往后挪n-1位,所有挪动次数相加是一个等差数列,则量级就为n^2^。
  3. 空间复杂度:O(1)
  4. 稳定性:稳定

希尔排序

希尔排序法又称缩小增量排序。
其基本思想如下:

  1. 先选定一个整数gap,将待排序的数据分成gap组,且所有距离为gap的分在一个组
  2. 对所有组分别进行排序
  3. 缩小gap,重新分组,对所有组别重新排序。
  4. 重复上述操作,待gap为1时,则进行插入排序,使其所有数据有序。

先来看看是如何分组的:
在这里插入图片描述

过程分析(以升序为例):

  1. 首先确定gap的初始值,这并没有一个确切的答案,在最开始首先定义gap = n(n为元素个数),但我们不能取n作为gap,会没有任何意义,一般取gap = gap/2或者是gap = gap/3+1作为初始值。
  2. 确定结束条件,即当gap>1则进入循环,然后根据gap = gap/2或者是gap = gap/3+1缩减gap,当循环判断gap==1时,说明在上一次循环时已经进行了直接插入排序,数列已经有序了,则不需要进入循环。
    因此外部大循环可写为如下:
int gap = n;//n是数据个数
while(gap > 1)
{//gap /= 2;gap = gap/3 + 1;//这两种写法都可以,都能保证在最后gap=1,使其进行直接插入排序//.....
}

下面则是单趟排序的过程:
在这里插入图片描述
单趟排序的过程和直接插入排序的过程差不多,我们直接来看代码:

void ShellSort(int* a, int n)//希尔排序
{int gap = n;while (gap > 1){gap = gap / 3 + 1;///保证最后一趟gap一定为1,进行插入排序for (int i = 0; i < n - gap; i++){//中间过程和直接插入排序一样int end = i;int tmp = a[end + gap];while (end >= 0){if (a[end] > tmp){a[end + gap] = a[end];end -= gap;}elsebreak;}a[end + gap] = tmp;}}
}

由代码发现,实际上并不是一组一组进行排序的,
在这里插入图片描述
希尔排序的特性总结:

  1. 希尔排序是对直接插入排序的优化
  2. gap>1时都属于是预排序:即分组插入排序,将大的数更快放到后面,小的数更快放到前面,目标是使序列接近有序
  3. gap==1时,就是直接插入排序,此时序列已经接近有序,再插入排序就会快很多。
  4. 希尔排序的时间复杂度不好计算,可以记住大约在O(N^1.3^)即可。

感谢大家观看,如果大家喜欢,希望大家一键三连支持一下,如有表述不正确,也欢迎大家批评指正。
请添加图片描述


http://www.mrgr.cn/news/35518.html

相关文章:

  • 解锁微前端的优秀库
  • 【机器学习】机器学习中用到的高等数学知识
  • Python学习从0到1 day26 第三阶段 Spark ④ 数据输出
  • 前端神经网络入门(三):深度学习与机器学习的关系、区别及核心理论支撑 - 以Brain.js示例
  • ubontu--cuDNN安装
  • Llama架构及代码详解
  • 阴影的基本原理
  • Linux驱动开发初识
  • mysql学习教程,从入门到精通,SQL RIGHT JOIN语句(24)
  • Robot Operating System——多边形数据
  • [大语言模型-论文精读] Diffusion Model技术-通过时间和空间组合扩散模型生成复杂的3D人物动作
  • Thread , ThreadLocal , ThreadLocalMap , Entry 之间的关系?
  • 宝塔部署vue项目出现的各种问题
  • 【算法】模拟:(leetcode)6.Z 字形变换(medium)
  • 光子架与电子架 -- 主从子架
  • 小程序面板开发教程|开发照明 Matter 面板步骤(一)
  • WebGL阴影与后期处理
  • Taro多端统一开发解决方案
  • 多线程:死锁
  • 从 Oracle 集群到单节点环境(详细记录一次数据迁移过程)之二:生产服务器的备份操作
  • 前端读取PDF和DOCX文件(干货分享)
  • 【C++】Eclipse技巧汇总
  • ATTCK实战系列-Vulnstack靶场内网域渗透(二)
  • [docker][软件]docker快速安装rabbitmq
  • 每日一练:二叉树的层序遍历
  • 并发编程。