C 语言排序算法详解:插入排序与希尔排序
插入排序
算法思想
插入排序的逻辑其实非常直观,就像我们平时整理扑克牌一样。假设手里已经有一组有序的牌,当拿到新的一张牌时,我们会从右往左依次比较,找到合适的位置将其插入。
在代码层面,这意味着对于每一个待插入的元素 tmp,我们需要将它与前面已排序序列中的元素逐一比较。如果 tmp 比前一个元素小,就继续向前找;如果 tmp 比前一个元素大,说明找到了位置,直接插入即可。
实现思路
- 确定范围:假设下标
0到end之间的数据已经是有序的。 - 准备插入:取
end + 1位置的元素作为tmp(待插入值)。 - 移动与比较:将
end位置的值与tmp比较。若tmp更小,则将end的值后移一位,end减一,继续向前比较;否则停止循环。 - 完成插入:循环结束后,将
tmp放入end + 1的位置。 - 遍历数组:重复上述过程,直到整个数组有序。
代码实现
// 插入排序
void InsertSort(int* a, int n) {
for (int i = 0; i < n - 1; i++) {
int end = i;
int tmp = a[end + 1];
while (end >= 0) {
if (tmp < a[end]) {
a[end + 1] = a[end];
end--;
} else {
break;
}
}
a[end + 1] = tmp;
}
}
注意这里 end 的移动逻辑,它保证了未排序部分的元素能够正确'腾出'空间给 tmp。
希尔排序
算法思想
希尔排序可以看作是插入排序的升级版。普通的插入排序在处理大规模数据时效率较低,因为每次只能移动相邻元素。希尔排序引入了一个间隔(gap)的概念,先将数组按间隔分组,对每组进行插入排序(预排序),然后不断缩小间隔,直到间隔为 1 时再进行最后一次插入排序。
这个过程让数组在最终排序前已经变得'基本有序',从而大幅减少了普通插入排序的比较和移动次数。


