插入排序
1、插入排序思想
插入排序的核心思想是逐步构建有序序列:
将数组分为'已排序'和'未排序'两部分,初始时已排序部分只包含第一个元素。
每次从未排序部分取出第一个元素,将其向前插入到已排序序列中的正确位置,使得插入后的序列依然保持有序。
重复这个过程,直到所有元素都被插入到已排序序列中。
这个过程就像整理扑克牌:你会把每一张新摸到的牌,插入到手中已排好序的牌堆里,最终让整副牌都有序。
2、示例代码
// 插入排序(此处为降序,升序将 a[end] < tmp 改为 a[end] > tmp)
void InsertSort(int* a, int n) {
// 遍历未排序元素(从第 2 个元素开始)
for (int i = 1; i < n; i++) {
int end = i - 1; // 已排序部分末尾下标
int tmp = a[i]; // 保存当前待插入元素
// 向前查找合适位置,大于 tmp(降序)则后移
while (end >= 0) {
if (a[end] < tmp) {
a[end + 1] = a[end]; // 元素后移腾位置
end--;
} else {
break; // 找到位置,退出循环
}
}
a[end + 1] = tmp; // 插入到正确位置
}
}
3、效率分析
时间复杂度:最坏情况下,插入第 1 个待排序元素时最多比较 1 次,第 2 个元素最多比较 2 次…… 第 n-1 个元素最多比较 n-1 次,总比较次数为等差数列求和,因此时间复杂度为O(N^2);但在数组已有序的情况下,每个元素仅需比较 1 次,时间复杂度可优化至O(N)。
空间复杂度:仅定义了常数级的辅助变量,未额外开辟大规模空间,因此空间复杂度为O(1)。
稳定性:排序是稳定的。因为元素是逐个向前插入的,当遇到相等元素时不会移动,因此相等元素的相对位置在排序前后保持不变。
希尔排序
1、希尔排序思想
希尔排序的核心思想是分组插入排序,逐步缩小增量:
将整个待排序数组按照某个增量(步长)分割成若干个子序列,每个子序列的元素在原数组中是等间隔的。对每个子序列分别进行插入排序,通过这种分组排序,让数组整体变得'基本有序'。


