插入排序
核心思想
插入排序的核心在于逐步构建有序序列。想象一下整理扑克牌,每摸到一张新牌,就把它插到手头已排好序的牌堆里合适的位置。初始时,第一个元素被视为有序,后续每个元素都向前查找位置并插入。

代码实现
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;
}
}
性能分析
时间复杂度通常是 O(N^2),但在数据基本有序时能优化到 O(N)。空间复杂度为 O(1),且是稳定排序。适合小规模或近似有序的数据场景。
希尔排序
核心思想
希尔排序是对插入排序的改进,核心是分组插入。先按较大增量将数组分成若干子序列进行插入排序,让整体变得'大致有序',再逐步缩小增量,直到增量为 1 时完成最终排序。这就像先把乱序的牌按花色分组整理,再按点数细分,最后整体微调。

不同教材对时间复杂度的分析略有差异,通常认为在 O(NlogN) 到 O(N^2) 之间,取决于增量序列的选择。
代码实现
void ShellSort(int* a, int n) {
gap = n;
(gap > ) {
gap = gap / + ;
( j = ; j < gap; j++) {
( i = j; i < n - gap; i += gap) {
end = i;
tmp = a[i + gap];
(end >= ) {
(tmp > a[end]) {
a[end + gap] = a[end];
end -= gap;
} {
;
}
}
a[end + gap] = tmp;
}
}
}
}




