插入排序
概述
插入排序(Insertion sort) 是一种简单直观的排序算法。
核心思想
将数组分为 已排序区间 和 未排序区间 ,每次从未排序区间取出一个元素, 在已排序区间中找到合适的位置插入(类似整理扑克牌)。
时间复杂度
插入排序的最优时间复杂度为 ,在数列几乎有序时效率很高。
插入排序的最坏时间复杂度和平均时间复杂度都为 。
空间复杂度
原地排序, ,不需要额外空间。
稳定性
插入排序是一种稳定的排序算法
伪代码
实现
function insertionSort(arr: number[]): number[] {
// 遍历未排序区间(从第二个元素开始)
for (let i = 1; i < arr.length; i++) {
const current = arr[i] // 当前待插入元素
let j = i - 1 // 从已排序区末尾开始比较
// 在已排序区间中寻找插入位置
while (j >= 0 && arr[j] > current) {
arr[j + 1] = arr[j] // 元素后移
j--
}
arr[j + 1] = current // 插入到正确位置
}
return arr
}
// 测试示例
const testArr = [5, 2, 4, 6, 1, 3]
console.log(insertionSort([...testArr])) // 输出: [1, 2, 3, 4, 5, 6]
执行过程示例 ([5, 2, 4, 6, 1, 3]
)
初始状态
已排序区 [5] | 未排序区 [2, 4, 6, 1, 3]
第一轮(插入 ):
- 比较 → 后移
- 插入 到首位 →
[2, 5] | [4, 6, 1, 3]
第二轮(插入 ):
- → 后移
- → 插入到 前 →
[2, 4, 5] | [6, 1, 3]
第三轮(插入 ):
- → 直接插入末尾 →
[2, 4, 5, 6] | [1, 3]
- → 直接插入末尾 →
第四轮(插入 ):
- 依次与 比较 → 全部后移
- 插入到首位 →
[1, 2, 4, 5, 6] | [3]
第五轮(插入 ):
- → 后移, → 插入 前
- 最终结果:
[1, 2, 3, 4, 5, 6]
优化
二分查找优化
// 二分查找优化(查找插入位置)
function insertionSortOptimized(arr: number[]) {
for (let i = 1; i < arr.length; i++) {
const current = arr[i]
const pos = binarySearch(arr, 0, i - 1, current)
// 整体后移元素
for (let j = i - 1; j >= pos; j--) {
arr[j + 1] = arr[j]
}
arr[pos] = current
}
return arr
}
二分插入排序:将比较操作优化至 ,但移动操作仍为