深入浅出排序算法之直接插入排序(拓展:折半插入排序)
目录
1. 图示解析
2. 原理解析
3. 代码实现
4. 性能分析
5. 折半插入排序(拓展)
直接插入排序和选择排序的第一趟就是第一个关键字 !
1. 图示解析
2. 原理解析
整个区间被分为:① 有序区间;② 无序区间
每次选择无序区间的第一个元素,在有序区间内选择合适的位置插入。
为了各位小伙伴能更加清楚地认识直接插入排序,我接下用文字描述直接插入排序的过程!
想通过一个例子来体会一下插入排序的执行流程。例如,对原始序列{49,38,65,97,76,13,27,49}进行直接插入排序的具体流程如下(序列中有两个49,其中一个加下划线,加以区分)。
原始序列:49 38 65 97 76 13 27 49
(1)一开始只看49,一个数当然是有序的。
有序序列:{49};无序序列:{38 65 97 76 13 27 49}
(2)向有序序列插入38,38 < 49,所以49向后移动一个位置,38插入到49原来的位置,这趟排序后的结果为:
有序序列:{38 49};无序序列:{ 65 97 76 13 27 49}
(3)向有序序列插入65,65 > 49,所以不需要移动,65就应该在49只有,这趟排序后的结果为:
有序序列:{38 49 65};无序序列:{97 76 13 27 49}
(4)插入97,97 > 65,所以不需要移动,97就应该在65之后,这趟排序后的结果为:
有序序列:{38 49 65 97};无序序列:{76 13 27 49}
(5)插入76,76 < 97,所以97向后移动一个位置,继续比较,76 > 65,65不需要移动,76应该插入在65之后,97之前,这趟排序后的结果为:
有序序列:{38 49 65 76 97};无序序列:{13 27 49}
(6)插入13,13 < 97,97后移;13 < 76,76后移;这样逐个向前比较,发现13应该插入在最前面,这趟排序后的结果为:
有序序列:{13 38 49 65 76 97};无序序列:{27 49}
(7)插入27,还是从后面前行比较,确定27应该插入在13之后、38之前,这趟排序后的结果为:
有序序列:{13 27 38 49 65 76 97};无序序列:{49}
(8)最后插入49,同样从后向前逐个比较,知道49 = 49 < 65,它的位置确定,直接插入排序全过程完成。最后的排序结果为:
有序序列:{13 27 38 49 49 65 76 97};无序序列:{}
总结算法思想:
每趟将一个待排序的关键字按照其值的大小插入到已经拍好的部分有序序列的位置上,直到所有待排序关键字都插入到有序序列中为止。
注意!!!!!!!!!!
小伙伴们请注意,我这里省略了i = 0的情况,从i = 1开始,也就是一开始只看49,一个数当然是有序的。如果是在考试中一定要把i = 0的情况作为第一趟(针对专升本和考研都一样)。
3. 代码实现
//直接插入排序public static void insertSort(int[] arr) {//代码可以从i = 1开始算起,但是做题画图时,一定要从i = 0开始算起for (int i = 1; i < arr.length; i++) {int j = i - 1;int tmp = arr[i];for (; j >= 0; j--) {//如果arr[j] > tmp变成arr[j] >= tmp就变成不稳定了if (arr[j] > tmp) {arr[j + 1] = arr[j];} else {break;}}arr[j + 1] = tmp;}}public static void main(String[] args) {int[] arr = {10,9,8,7,6,5,4,3,2,1};Sort.insertSort(arr);for (int x : arr) {System.out.print(x + " ");}}
4. 性能分析
时间复杂度 | 空间复杂度 | ||
最好 | 平均 | 最坏 | |
O(N) | O(N^2) | O(N^2) | O(1) |
数据有序 | 数据逆序 |
稳定性:稳定
如果一个排序是稳定的,那么就可以实现为不稳定的
但是如果一个算法本身是不稳定的,你没办法实现为稳定的排序
插入排序,原始数据越有序,时间效率越高!
检测一下:
//创建升序数组public static void createArray1(int[] arr){for(int i = 1;i<10000;i++){arr[i - 1] = i;}}//创建逆序数组public static void createArray2(int[] arr){for(int i = 0;i<10000;i++){arr[i] = 10000 - i;}}public static void main(String[] args) {int[] arr1 = new int[10000];Test.createArray1(arr1);long s1 = System.currentTimeMillis();Sort.insertSort(arr1);long e1 = System.currentTimeMillis();System.out.println("数组有序的情况:"+(e1 - s1));int[] arr2 = new int[10000];Test.createArray2(arr2);long s2 = System.currentTimeMillis();Sort.insertSort(arr2);long e2 = System.currentTimeMillis();System.out.println("数组逆序的情况:"+(e2 - s2));}
5. 折半插入排序(拓展)
在有序区间选择数据应该插入的位置时,因为区间的有序性,可以利用折半查找的思想来增加插入算法的效率!
//折半插入排序public static void bsInsertSort(int[] arr) {//代码可以从i = 1开始算起,但是做题画图时,一定要从i = 0开始算起for (int i = 1; i < arr.length; i++) {int v = arr[i];int left = 0;//左边标记永远从0下标开始int right = i;while(left < right){int mid = (left + right) / 2;//需要[left right)if(arr[mid] < v){//如果区间要闭,就赋值mid + 1或者mid - 1left = mid + 1;}else{//如果右区间要开,就赋值midright = mid;}}for (int j = i; j > left; j--) {arr[j] = arr[j - 1];}arr[left] = v;}}
相关文章:

深入浅出排序算法之直接插入排序(拓展:折半插入排序)
目录 1. 图示解析 2. 原理解析 3. 代码实现 4. 性能分析 5. 折半插入排序(拓展) 直接插入排序和选择排序的第一趟就是第一个关键字 ! 1. 图示解析 2. 原理解析 整个区间被分为:① 有序区间;② 无序区间 每次选…...

皮卡丘RCE靶场通关攻略
皮卡丘RCE靶场通关攻略 文章目录 皮卡丘RCE靶场通关攻略RCE(remote command/code execute)概述远程系统命令执行启动环境漏洞练习第一关exec "ping"第二关 exec "eval" RCE(remote command/code execute)概述 RCE漏洞,可以让攻击者直接向后台服…...
Mysql binlog日志功能使用,简单易懂
一、简单了解binlog MySQL的二进制日志binlog可以说是MySQL最重要的日志,它记录了所有的DDL和DML语句(除了数据查询语句select)。因此binlog日志文件我们用cat等查看文件的命令是打不开的,但是mysql提供了专门看binlog文件的命令…...

计算机视觉-光源的目的和作用
光源的目的 机器视觉系统的核心是图像采集和图像处理,而光源则是影响图像水平的重要因素,通过适当的光源照明,使图像中的目标信息与背景信息得到更好的分离,可大大降低图像识别难度,提高系统的精度和可靠性。 对于机器…...

源码角度分析Java 循环中删除数据为什么会报异常
一、源码角度分析Java 循环中删除数据为什么会报异常 相信大家在之前或多或少都知道 Java 中在增强 for中删除数据会抛出:java.util.ConcurrentModificationException 异常,例如:如下所示程序: public class RmTest {public sta…...

leetCode 229. 多数元素 II + 摩尔投票法 + 进阶 + 优化空间
229. 多数元素 II - 力扣(LeetCode) 给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。 进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1)的算法解决此问题。 (1)哈希表 class …...

5 个编写高效 Makefile 文件的最佳实践
在软件开发过程中,Makefile是一个非常重要的工具,它可以帮助我们自动化构建、编译、测试和部署。然而,编写高效的Makefile文件并不是一件容易的事情。在本文中,我们将讨论如何编写高效的Makefile文件,以提高我们的开发…...
20231028刷题记录
P3381 【模板】最小费用最大流 Portal. sol. 注意 SPFA 找最小费用增广路时不要到终点就返回,因为到终点的路径可能有多条不能确定哪条是费用最小的。 P2740 [USACO4.2] 草地排水Drainage Ditches Portal. 最大流模板。 注意区分 N , M N,M N,M。 CF609D G…...
39 深度学习(三):tensorflow.data模块的使用(基础,可跳)
文章目录 data模块的使用基础api的介绍csv文件tfrecord data模块的使用 在训练的过程中,当数据量一大的时候,我们纯读取一个文件,然后每次训练都调用相同的文件,然后进行处理是很不科学的,或者说,当我们需…...

css四种导入方式
1 行内样式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body> <h1 style"color: blue">我是标题</h1> </body> </htm…...

Linux学习第24天:Linux 阻塞和非阻塞 IO 实验(一): 挂起
Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 在正式开始今天的笔记之前谈一下工作中遇见的一个问题。 本篇笔记主要学习Linux 阻塞和非阻塞 IO 实验,主要包括阻塞和非阻塞简介、等待队列、轮询、…...

037-第三代软件开发-系统音量设置
第三代软件开发-系统音量设置 文章目录 第三代软件开发-系统音量设置项目介绍系统音量设置QML 实现C 实现 总结一下 关键字: Qt、 Qml、 volume、 声音、 GPT 项目介绍 欢迎来到我们的 QML & C 项目!这个项目结合了 QML(Qt Meta-Obj…...

Python 自动化详解(pyautogui)
文章目录 1 概述1.1 第三方库:pyautogui1.2 坐标说明 2 操作对象2.1 鼠标2.1.1 定位2.1.2 移动2.1.3 拖动2.1.4 滚动2.1.5 点击 2.2 键盘2.2.1 输入2.2.2 按键2.2.3 快捷键 2.3 屏幕2.3.1 截图2.3.2 分辨率 2.4 信息提示2.4.1 提示框2.4.2 选择框2.4.3 密码输入2.4.…...

【Linux】第四站:Linux基本指令(三)
文章目录 一、时间相关的指令1.指令简介2.使用 二、cal指令三、find指令 -name1.介绍2.使用 四、grep指令1.介绍2.使用 五、zip/unzip指令1.介绍2.zip的安装3.使用 六、tar指令:打包解包,不打开它、直接看内容1.介绍2.使用 七、bc指令八、uname -r指令1.…...

SpringBoot内置工具类之断言Assert的使用与部分解析
先例举一个service的demo中用来验证参数对象的封装方法,使用了Assert工具类后是不是比普通的 if(xxx) { throw new RuntimeException(msg) } 看上去要简洁多了? 断言Assert工具类简介 断言是一个判断逻辑,用来检查不该发生的情况ÿ…...
如何检测租用的香港服务器是不是CN2线路呢?
CN2,是中国电信新一代融合承载网络,是为电信自身关键业务和具有QoS保证的SLA业务服务的,可以提供高性能的网络指 标,平均单向时延、最大单向时延、单向丢包率等均属于顶尖水平。简单地说,CN2和普通网络,就像…...

Spring Boot进阶(94):从入门到精通:Spring Boot和Prometheus监控系统的完美结合
📣前言 随着云原生技术的发展,监控和度量也成为了不可或缺的一部分。Prometheus 是一款最近比较流行的开源时间序列数据库,同时也是一种监控方案。它具有极其灵活的查询语言、自身的数据采集和存储机制以及易于集成的特点。而 Spring Boot 是…...

Redis(02)| 数据结构-SDS
一、键值对数据库是怎么实现的? 在开始讲数据结构之前,先给介绍下 Redis 是怎样实现键值对(key-value)数据库的。 Redis 的键值对中的 key 就是字符串对象,而 value 可以是字符串对象,也可以是集合数据类型…...

HackTheBox-Starting Point--Tier 0---Preignition
文章目录 一 题目二 实验过程 一 题目 Tags Web、Custom Applications、Apache、Reconnaissance、Web Site Structure Discovery、Default Credentials译文:Web、定制应用程序、Apache、侦察、网站结构发现、默认凭证Connect To attack the target machine, you …...

售货机相关的电路
一、货道选通矩阵电路,类似扫描电路,驱动哪个电机,就打开相应的行线与列线输出 二、MDB纸币器,虽然现在国内都是手机支付,但如果机器还是外销国外还是有用 三、硬币器电路,投币与退币,脉冲信号…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...