插入排序
基本思想(从小到大排序)
1、n个待排序元素看作一个有序表(左),一个无序表(右),初始有序表只含一个元素,无序表含n-1个元素
2、每次从无序表取出第一个元素,把它与有序表最后一个元素倒序比较
3、将它插入到有序表适当位置,直到无序表元素为0
插入方式
1、直接插入排序:在添加新的记录时,使用顺序查找的方式找到其要插入的位置,然后将新记录插入
2、折半插入排序:使用折半查找来代替顺序查找,减少比较次数
3、2-路插入排序:在折半插入排序的基础上对其进行改进,减少其在排序过程中移动记录的次数从而提高效率
(1)利用一个与排序序列一样大小的数组作为辅助空间,设置 first 和 final 指针标记辅助数组开始位置和最后位置
(2)遍历未排序序列
(3)如果待插入元素比已排序序列最小的元素(first)小,则 first 位置前移,将待排序元素插入 first 位置
(4)如果待插入元素比已排序序列最大的元素(final)大,则 final 位置后移,将待排序元素插入 final 位置
(5)如果待插入元素比最小大,比最大小,则需要移动元素,过程类似直接插入排序,不过考虑到循环使用数组,对于下标的处理有些许不同
(6)处理完最后一个元素后,将排序记录复制到原来的顺序表里
4、表插入排序
(1)1、2、3 基本结构都采用数组的形式进行存储,因而无法避免排序过程中产生的数据移动的问题,如果想要从根本上解决只能改变数据的存储结构,改用链表存储
(2)使用链表的存储结构对数据进行插入排序,在对记录按照其关键字进行排序的过程中,不需要移动记录的存储位置,只需要更改结点间指针的指向
代码实现
public class InsertSort {//从小到大排序
//移动法
public static void insertSort(int[] array) {
if (array == null || array.length <= 1) {
return;
}
//有序表在左,无序表在右;有序表第一个元素索引为0,无序表第一个元素索引为1
for (int i = 1; i < array.length; i++) {//遍历无序表,从索引1到索引array.length-1
int insert = array[i];//储存无序表第一个元素
int index = i - 1;//储存有序表最后一位元素的索引
while (index >= 0 && insert < array[index]) {//index >= 0,保证下标不越界
array[index + 1] = array[index];//有序表中与insert比较过且大于insert的元素都右移一位
index--;//从有序表的最后一位元素开始,倒序遍历比较有序表
}//完全遍历有序表或找到比insert大的元素就退出循环
array[index + 1] = insert;//index = -1,insert插入有序表第一位;或插入第一个比insert小的元素的右一位
}
}
//省略交换法的实现,时间:交换法 > 移动法,因为访问数组的次数更少
}
对于随机排列的长度为 N 且主键不重复的数组
1、比较的总次数是交换的次数加上一个额外的项,该项为 N 减去被插入的元素正好是已知的最小元素的次数
(1)在最坏情况下(逆序数组),这一项相对于总数可以忽略不计
(2)在最好情况下(数组已经有序),这一项等于 N-1
2、插入排序所需的时间取决于输入中元素的初始顺序
(1)对一个很大且其中的元素已经有序(或接近有序)的数组进行排序,将会比对随机顺序的数组或是逆序数组进行排序要快得多
(2)插入排序对一个有序数组进行排序时,能够立即发现每个元素都已经在合适的位置之上,它的运行时间也是线性的
(3)插入排序对于部分有序的数组十分高效,也很适合小规模数组
3、部分有序的数组
(1)数组中倒置的数量小于数组大小的某个倍数
(2)倒置指的是数组中的两个顺序颠倒的元素
4、典型部分有序数组
(1)数组中每个元素距离它的最终位置都不远
(2)一个有序的大数组接一个小数组
(3)数组中只有几个元素的位置不正确
5、插入排序需要的交换操作 = 数组中倒置的数量,倒置的数量 + 数组大小 - 1 >= 需要的比较次数 >= 倒置的数量
(1)每次交换都改变了两个顺序颠倒的元素的位置,相当于减少了一对倒置,当倒置数量为0 时,排序就完成了
(2)每次交换都对应着一次比较,且 1 到 N-1 之间的每个 i 都可能需要一次额外的比较(在 a[i] 没有达到数组的左端时)
6、大幅提高插入排序的速度,只需要在内循环中将较大的元素都向右移动而不总是交换两个元素,这样访问数组的次数就能减半
7、对于随机排序的无重复主键的数组,插入排序和选择排序的运行时间是平方级别的,两者之比应该是一个较小的常数
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战