1️⃣ 希尔排序(Shell Sort)简介
希尔排序是 插入排序的一种改进 ,它由 Donald Shell 于 1959 年提出,也叫 缩小增量排序。
核心思想:
- 插入排序在数据量大或者序列几乎倒序时效率低,因为每次只能移动相邻元素。
- 希尔排序通过设置一个 "间隔 gap",把序列分成若干子序列,然后对每个子序列进行插入排序。
- 随着排序进行,gap逐渐减小,最后当 gap = 1 时,整个数组已经接近有序,这时做最后一轮插入排序效率很高。
简单步骤:
- 选择一个增量序列 gap(初始通常是 n/2)。
- 按 gap 把数组划分成若干个子序列。
- 对每个子序列进行插入排序。
- 缩小 gap(通常 gap = gap / 2),重复步骤 2~3。
- 直到 gap = 1,做最后一次插入排序。
示意(此处只是举例方便,gap为3):
假设数组 [8, 5, 3, 7, 6, 2, 4, 1],gap = 3,序列分组:
- 第1组:8, 7, 4
- 第2组:5, 6, 1
- 第3组:3, 2
每组内部插入排序,然后再减 gap,最后 gap = 1 时做整体插入排序。
2️⃣ 插入排序(Insertion Sort)简介
核心思想:
- 每次从未排序的部分取一个元素,插入到已排序部分的合适位置。
- 适合数据量小或者几乎有序的序列。
- 时间复杂度:
- 最好 O(n)(已排序)
- 最坏 O(n²)(逆序)
- 平均 O(n²)
步骤:
- 从第 2 个元素开始(第 1 个默认已排序)。
- 比较该元素和已排序序列,从右向左找到合适位置。
- 插入该元素,右侧元素后移。
- 重复直到排序完成。
3️⃣ 希尔排序 vs 插入排序
| 特点 | 插入排序 | 希尔排序 |
|---|---|---|
| 核心思想 | 每次插入一个元素到已排序序列 | 先分组插入排序,逐步减小间隔,最后整体插入 |
| 适用情况 | 小规模或接近有序 | 大规模数据更优于插入排序 |
| 时间复杂度 | O(n²) 平均/最坏 | 最好 O(n log² n) ~ O(n^(3/2))(依增量序列不同) |
| 性能瓶颈 | 数据量大,逆序时移动次数多 | 通过"间隔分组"减少元素移动次数 |
| 稳定性 | 稳定 | 不稳定(同一组元素可能跨组移动) |
总结一句话:
希尔排序是"分组插入排序",通过缩小间隔让数组逐步接近有序,从而提高效率。
具体演示
以数组 [8, 5, 3, 7, 6, 2, 4, 1] 来演示 希尔排序 的整个过程。为了简单,采用 gap 序列取 n/2、n/4、...直到 1 的方式,也就是经典做法。
初始数组:
[8, 5, 3, 7, 6, 2, 4, 1]
长度 n = 8,初始 gap = 8 / 2 = 4
第 1 轮:gap = 4
分组方式:
- 第1组:8, 6
- 第2组:5, 2
- 第3组:3, 4
- 第4组:7, 1
对每组进行 插入排序:
- 第1组
[8, 6]→ 排序后[6, 8] - 第2组
[5, 2]→[2, 5] - 第3组
[3, 4]→[3, 4](已排序) - 第4组
[7, 1]→[1, 7]
合并后,数组变为:
[6, 2, 3, 1, 8, 5, 4, 7]
第 2 轮:gap = 2
分组方式:
- 第1组:6, 3, 8, 4 →
[6, 3, 8, 4] - 第2组:2, 1, 5, 7 →
[2, 1, 5, 7]
分别做插入排序:
- 第1组
[6, 3, 8, 4]- 插入 3 →
[3, 6, 8, 4] - 插入 8 →
[3, 6, 8, 4](不动) - 插入 4 →
[3, 4, 6, 8]
- 插入 3 →
- 第2组
[2, 1, 5, 7]- 插入 1 →
[1, 2, 5, 7] - 插入 5 →
[1, 2, 5, 7](不动) - 插入 7 →
[1, 2, 5, 7](不动)
- 插入 1 →
合并后,数组变为:
[3, 1, 4, 2, 6, 5, 8, 7]
第 3 轮:gap = 1
此时就是普通 插入排序:
- 初始数组:
[3, 1, 4, 2, 6, 5, 8, 7] - 插入 1 →
[1, 3, 4, 2, 6, 5, 8, 7] - 插入 4 →
[1, 3, 4, 2, 6, 5, 8, 7](不动) - 插入 2 →
[1, 2, 3, 4, 6, 5, 8, 7] - 插入 6 →
[1, 2, 3, 4, 6, 5, 8, 7](不动) - 插入 5 →
[1, 2, 3, 4, 5, 6, 8, 7] - 插入 8 →
[1, 2, 3, 4, 5, 6, 8, 7](不动) - 插入 7 →
[1, 2, 3, 4, 5, 6, 7, 8]
✅ 最终排序结果:
[1, 2, 3, 4, 5, 6, 7, 8]