这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战
插入排序
插入排序是一种简单的排序算法,插入排序将一组数据分为有序区间和无序区间,每次从无序区间找到合适的一个数据插入到有序区间的合适位置,当无序区间没数据,即只剩下有序区间时,这组数据就变为完全有序。
算法描述
假设是从小到大排序
- 将一组数据的首个数据组成有序区间,其他数据组成无序区间
- 在无序区间抽出首个数据 A
- A 依次与有序区间的各个数据进行对比。若遇到数据比 A 大的,则将 A 插入到该数据的前面一个位置,若 A 比有序区间的任何数据都要大,则插入到有序区间末尾。总之,保证插入后的有序区间依然有序。
- 重复 2 和 3 操作,直到无序区间没有数据
算法图解
假设一组数据里有:3、5、4、1、2。
“第一次插入”步骤,3 作为一个有序区间,5、4、1、2 作为无序区间。标记无序区间的首个数据 5,与有序区间的数据 3 作对比,5 比 3 大,由于有序区间后面没有数据了,所以 5 插入到有序区间的 3 后面。
“第二次插入”步骤,3、5 作为有序区间,4、1、2 作为无序区间。标记无序区间的首个数据 4,与有序区间的 3 作对比,4 比 3 大,因此需要继续与后面一个数据对比。4 与有序区间的 5 作对比,比 5 小,因此 4 插入到有序区间的 5 的前面。
“第三次插入”步骤,同样地,标记无序区间的首个数据 1,1 与有序区间的 3 对比,1 比 3 小,插入到 3 的前面。
“第四次插入”步骤,无序区间唯一的数据 2,比有序区间的 1 大,比有序区间的 3 小,因此插入 3 的前面。到了这里,整组数据就已经达到了完全有序。
有没有发现,插入排序特别像抽扑克牌?
手上的牌是有序区间,放在桌子上的牌堆是无序区间,每次抽牌时,都要依次与手上的每张牌进行对比,并将该牌插入到相应的位置,保证手上的牌有序。当牌堆抽完了,手上的整副扑克牌就是有序了。
代码实现
// 插入排序
function insertionSort(arr) {
if (arr.length <= 1) {
return arr
}
for (var i=1; i<arr.length; i++) {
var j = i - 1 // j 是有序区间的最大下标
var val = arr[i] // val 是无序区间的首个数据,用来与有序区间的各个数做对比
for (; j>=0; j--) {
if (arr[j] > val) { // 由于要求排序从小到大,也就是说 val 比 arr[j] 小的时候,val 需要排在 arr[j] 前面,arr[j] 需要移位
arr[j+1] = arr[j]
} else {
break // 当不需要移位时,由于有序区间是有序的,直接跳出循环即可
}
}
arr[j+1] = val
}
return arr
}
原地排序 | 稳定性 | 最好时间复杂度 | 最坏时间复杂度 | 平均时间复杂度 | 插入排序 | 是 | 稳定 | O(n) | O(n²) | O(n²) |
---|
插入排序其实是可以改进优化的,优化版的插入排序叫希尔排序,后面再做介绍。
js 算法系列文章推荐
- js 算法 - 冒泡排序 (juejin.cn)
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!