[排序算法]插入排序+希尔排序全梳理!

目录

  • 1.排序是什么?
    • 1.1排序的概念
    • 1.2排序运用
    • 1.3常见的排序算法
  • 2.插入排序分类
  • 3.直接插入排序
    • 基本思想
    • 具体步骤:
    • 动图演示
    • 代码实现
    • 直接插入排序的特性总结:
  • 4. 希尔排序
    • 基本思想
    • 具体步骤
    • 动图演示
    • 代码实现
    • 希尔排序的特性总结:
  • 5.总结

1.排序是什么?

1.1排序的概念

排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i] = r[j],且 r[i] 在 r[j] 之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
内部排序:数据元素全部放在内存中的排序。
外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不断地在内外存之间移动数据的排序。

1.2排序运用

这里给大家举几个生活中,常见排序的例子:

购物平台里面按某个商品的维度排序:
在这里插入图片描述
报考志愿时全国高校的排名情况:
在这里插入图片描述

其实在我们日常生活中会经常使用排序,可见排序与我们生活息息相关。

1.3常见的排序算法

在这里插入图片描述

2.插入排序分类

插入排序可以分为:直接插入排序希尔排序
在这里插入图片描述

3.直接插入排序

基本思想

直接插入排序的思路和打扑克牌时给牌排序的思路类似:

比如比如我手中有红桃 6,7,9,10 这 4 张牌,已经处于升序排列:
在这里插入图片描述
这时候,我又抓到一张黑桃 8,如何让手中的 5 张牌重新变成升序呢?

在这里插入图片描述
很简单,其实是在已经有序的 4 张牌中找到红桃 8 应该插入的位置,也就是 7 和 9 之间,把红桃 8 插进去:

在这里插入图片描述

就像玩牌一样,插入排序算法也采用了类似的思想:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。

具体步骤:

1)维护一个有序区,把元素一个个插入有序区的适当位置,直到所有元素都有序为止。
2)在待排序的元素中,假设前 n-1 个元素已有序,现将第 n 个元素插入到前面已经排好的序列中,使得前 n 个元素有序。按照此法对所有元素进行插入,直到整个序列有序。

接下来演示一下直接插入排序在数组中的具体实现步骤。

给定一组无序数组如下:

在这里插入图片描述
我们把首元素 6 作为有序区,此时有序区只有这一个元素:
在这里插入图片描述

第一轮,让元素 9 和有序区的元素依次比较,9 > 6,所以元素 9 和元素 6 无需交换。

此时有序区的元素增加到两个:

在这里插入图片描述

第二轮,让元素 7 和有序区的元素依次比较,7 < 9,所以把元素 7 和元素 9 进行交换:
在这里插入图片描述
7 > 6,所以把元素 7 和元素 6 无需交换。

此时有序区的元素增加到三个:

在这里插入图片描述

第三轮,让元素 4 和有序区的元素依次比较,4 < 9,所以把元素 4 和元素 9 进行交换:
在这里插入图片描述
4 < 7,所以把元素 4 和元素 7 进行交换:
在这里插入图片描述

4 < 6,所以把元素 4 和元素 6 进行交换:
在这里插入图片描述

此时有序区的元素增加到四个:
在这里插入图片描述

以此类推,插入排序一共会进行(数组长度-1)轮,每一轮的结果如下:
在这里插入图片描述

动图演示

我们来看一组动图演示:
在这里插入图片描述

代码实现

void InsertSort(int* a, int n) {//数组的长度是n,那么最后一个数据是n-1,倒数第二个数据是n-2for (int i = 0; i < n - 1; ++i) {// [0 end]有序,把end+1的位置的值插入进去,保持它依旧有序int end = i; //记录有序序列的最后一个元素的下标int tmp = a[end + 1]; //待插入的元素while (end >= 0) {if (tmp < a[end]) {a[end + 1] = a[end];--end;}else {break;}}//代码执行到此位置有两种情况://1.待插入元素找到应插入位置(break跳出循环到此)。//2.待插入元素比当前有序序列中的所有元素都小(while循环结束后到此)。a[end + 1] = tmp;}
}

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

  1. 元素集合越接近有序,直接插入排序算法的时间效率越高
  2. 时间复杂度:O(N^2)

最好的情况:数组是有序的或者接近有序的,那么时间复杂度就是:O(N)
最坏的情况:数组是逆序的,那么时间复杂度就是: O(N^2)
元素集合越接近有序,直接插入排序算法的时间效率越高。

  1. 空间复杂度:O(1),这里没有额外开辟空间.
  2. 稳定性:稳定。 直接插入排序在遇到相同的数时,可以就放在这个数的后面,就可以保持稳定性了,所以说这个排序是稳定的。

4. 希尔排序

基本思想

希尔排序法又称缩小增量法。

希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进。

它的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。

具体步骤

具体步骤是:

1)先选定一个小于 N 的整数 gap 作为第一增量,然后将所有距离为 gap 的元素分在同一组,并对每一组的元素进行直接插入排序。然后再取一个比第一增量小的整数作为第二增量,重复上述操作。
2)当增量的大小减到1时,就相当于整个序列被分到一组,进行一次直接插入排序,排序完成。

为什么要让 gap 由大到小呢?

原因是:

gap 越大,数据挪动得越快。

gap 越小,数据挪动得越慢。

前期让 gap 较大,可以让大的数据可以更快到最后,小的数可以更快到前面,减少挪动次数。

一般情况下,取序列的一半作为增量,然后依次减半,直到增量为 1

给定一组无序数组如下:

在这里插入图片描述
第一轮,我们用序列长度的一半作为第一次排序时 gap 的值,此时相隔距离为 5 的元素被分为一组(共分了 5 组,每组有 2 个元素),然后分别对每一组进行直接插入排序。

在这里插入图片描述

第二轮,gap 的值折半,此时相隔距离为 2 的元素被分为一组(共分了 2 组,每组有 5 个元素),然后再分别对每一组进行直接插入排序。
在这里插入图片描述

第三轮,gap 的值再次减半,此时 gap 减为 1,即整个序列被分为一组,进行一次直接插入排序。
在这里插入图片描述

动图演示

我们来看一组动图演示:
在这里插入图片描述

代码实现

/*希尔排序
* 时间复杂度:O(N)
* 如果gap越小,越接近有序;
* gap越大,那么大的数据可以更快到最后,小的数可以更快到前面,但它不接近有序
*/
void ShellSort(int* a, int n) {//1. gap>1 预排序//2. gap == 1 直接插入排序int gap = n;while (gap > 1) {gap = gap / 3 + 1;//进行一趟排序for (int i = 0; i < n - gap; ++i) {int end = i;int tmp = a[end + gap];while (end >= 0){if (tmp < a[end]) {a[end + gap] = a[end];end -= gap;}else {break;}}a[end + gap] = tmp;}}
}

希尔排序的特性总结:

  1. 希尔排序是对直接插入排序的优化。

  2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就
    会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。

  3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的
    希尔排序的时间复杂度都不固定:
    《数据结构(C语言版)》— 严蔚敏
    在这里插入图片描述

《数据结构-用面相对象方法与C++描述》— 殷人昆
在这里插入图片描述
因为我们的 gap 是按照 Knuth 提出的方式取值的,而且 Knuth 进行了大量的试验统计,我们暂时就按照:O(n1.25)到
O ( 1.6 ∗ n 1.25 ) 来计算。

时间复杂度:(N*logN),平均时间复杂度:O ( n 1.3)

空间复杂度:O ( 1 )

5.总结

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot项目本地运行正常,jar包运行时前端报错403:No mapping for......

SpringBoot项目本地运行正常&#xff0c;jar包运行时前端报错403&#xff1a;No mapping for… 提示&#xff1a;在部署jar包到云服务器上之前&#xff0c;一定要在本地运行jar包&#xff0c;查看前端代码是否运行正常&#xff0c;若报错的话可以节省很多时间 方式&#xff1a;…

面向Java程序员的Go工程开发入门流程

对于一个像我这样没有go背景的java程序员来说&#xff0c;使用go开发一个可用的程序的速度是肉眼可见的缓慢。 其难点不在于go语言本身&#xff0c;而是搭建整个工程链路的过程&#xff0c;即所谓的“配环境”。 本文主要讲述如何配出一个适合go开发的环境&#xff0c;以免有同…

Spring 源码:深度解析AOP源码配置解析

文章目录 一、 解析AOP配置的入口1.1 从XML配置到AOP Namespace的解析流程1.2 分析注解驱动的AOP配置解析流程 二、AOP配置解析的核心流程2.1 ConfigBeanDefinitionParser 类2.2 parse()2.3 parseAdvisor()2.4 parseAspect()2.5 parsePointcut()2.6 createAdvisorBeanDefinitio…

[C#]使用C#部署yolov8的obb旋转框检测tensorrt模型

【测试通过环境】 win10 x64 vs2019 cuda11.7cudnn8.8.0 TensorRT-8.6.1.6 opencvsharp4.9.0 .NET Framework4.7.2 NVIDIA GeForce RTX 2070 Super 版本和上述环境版本不一样的需要重新编译TensorRtExtern.dll&#xff0c;TensorRtExtern源码地址&#xff1a;TensorRT-CShar…

最佳 Mac 数据恢复:恢复 Mac 上已删除的文件

尝试过许多 Mac 数据恢复工具&#xff0c;但发现没有一款能达到宣传的效果&#xff1f;我们重点介绍最好的 Mac 数据恢复软件 没有 Mac 用户愿意担心数据丢失&#xff0c;但您永远不知道什么时候会发生这种情况。无论是意外删除 Mac 上的重要文件、不小心弄湿了 Mac、感染病毒…

【MySQL用户管理】

文章目录 1.用户信息2.创建用户3.删除用户4.修改用户密码5.给用户设置权限展示zhangsan用户的权限 6.回收权限 1.用户信息 host&#xff1a; 表示这个用户可以从哪个主机登陆&#xff0c;如果是localhost&#xff0c;表示只能从本机登陆 user&#xff1a; 用户名 authenticatio…

【记忆化搜索 】2312. 卖木头块

本文涉及知识点 记忆化搜索 LeetCode2312. 卖木头块 给你两个整数 m 和 n &#xff0c;分别表示一块矩形木块的高和宽。同时给你一个二维整数数组 prices &#xff0c;其中 prices[i] [hi, wi, pricei] 表示你可以以 pricei 元的价格卖一块高为 hi 宽为 wi 的矩形木块。 每…

【刷题(12)】图论

一、图论问题基础 在 LeetCode 中&#xff0c;「岛屿问题」是一个系列系列问题&#xff0c;比如&#xff1a; 岛屿数量 &#xff08;Easy&#xff09;岛屿的周长 &#xff08;Easy&#xff09;岛屿的最大面积 &#xff08;Medium&#xff09;最大人工岛 &#xff08;Hard&…

数据库设计:实体关系图

一个良好的设计对于数据库系统至关重要&#xff0c;它可以减少数据冗余&#xff0c;确保数据的一致性和完整性&#xff0c;同时使得数据库易于维护和扩展。 实体关系图&#xff08;Entity-Relationship Diagram、ERD&#xff09;是一种用于数据库设计的结构图&#xff0c;它描…

使用LLaMA-Factory微调大模型

使用LLaMA-Factory微调大模型 github 地址 https://github.com/hiyouga/LLaMA-Factory 搭建环境 git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory在 LLaMA-Factory 路径下 创建虚拟环境 conda create -p ./venv python3.10激活环境 c…

arduino + ov7670实现拍照

前言 用一个几块钱的 ov7670 摄像头加 arduino 来进行拍照实现。本文只是实现了模块的拍照功能。没有进行深入的研究&#xff0c;拍出来的视频不是流畅的&#xff0c;大概间隔6s会刷新一次。 图片预览 视频预览 arduino和ov7670实现拍照-哔哩哔哩 材料准备 材料数量价格(r…

北京大学第一医院与智源研究院共同发布基于可信执行环境的AI医学影像挑战赛

肾动脉狭窄是导致继发性高血压及肾功能不全的常见原因&#xff0c;而目前针对肾动脉狭窄功能学的评估尚处于探索阶段。数据保护和可信计算环境是目前人工智能技术应用于临床研究的一大瓶颈。北京大学第一医院与北京智源人工智能研究院心脏AI 联合研究中心特发布基于可信执行环境…

信号与槽函数的魔法:QT 5编程中的核心机制

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、信号与槽函数的基本概念 二、信号与槽函数的实现原理 三、信号与槽函数的代码实例 四…

npm镜像源管理、nvm安装多版本node异常处理

查看当前使用的镜像源 npm config get registry --locationglobal 设置使用官方源 npm config set registry https://registry.npmjs.org/ --locationglobal 设置淘宝镜像源 npm config set registry https://registry.npm.taobao.org/ --locationglobal 需要更改淘宝镜像源地址…

03.k8s常用的资源

3.k8s常用的资源 3.1 创建pod资源 k8s yaml的主要组成 apiVersion: v1 api版本 kind: pod 资源类型 metadata: 属性 spec: 详细上传nginx镜像文件&#xff0c;并且上传私有仓库里面 k8s_pod.yaml apiVersion: v1 kind: Pod metadata:name: nginxlabels:app: we…

自制数据#国家2000投影带划分范围shp(高斯克吕格 3°/6°分带)

国家2000投影分带范围&#xff08;3&#xff09; https://www.123pan.com/s/lqEljv-xvCHA.html 国家2000投影分带范围&#xff08;6&#xff09; https://www.123pan.com/s/lqEljv-xvCHA.html 声明&#xff1a;转载此文不为商业用途。文字和图片版权归原作者所有&#xff0c;…

【Python编程实践2/3】Python图像处理模块(上)

目录 引言 目标 安装模块 Windows系统 macOS系统 路径 Windows路径 ​编辑macOS路径 windows路径报错 windows路径前的r 示例代码 windows快速查看路径 macOS快速查看路径 打开图片 展示图片 下节预告 总结 引言 欢迎各位大佬垂阅本篇Python实践博客&a…

vue-Dialog 自定义title样式

展示结果 vue代码 <el-dialog :title"title" :visible.sync"classifyOpen" width"500px" :showClose"false" class"aboutDialog"> <el-form :model"classifyForm" :rules"classifyRules">…

【赠书第26期】AI绘画教程:Midjourney使用方法与技巧从入门到精通

文章目录 前言 1 Midjourney入门指南 1.1 注册与登录 1.2 界面熟悉 1.3 基础操作 2 Midjourney进阶技巧 2.1 描述词优化 2.2 参数调整 2.3 迭代生成 3 Midjourney高级应用 3.1 创意启发 3.2 团队协作 3.3 商业应用 4 总结与展望 5 推荐图书 6 粉丝福利 前言 在…

自动控制:控制系统的稳定性

自动控制&#xff1a;控制系统的稳定性 在自动控制领域&#xff0c;控制系统的稳定性是一个至关重要的问题。稳定性决定了系统在受到扰动后是否能够恢复到平衡状态。本文将介绍控制系统稳定性的基本概念、如何利用特征值分析稳定性&#xff0c;并通过具体示例和Python代码展示…