概念
希尔排序 = 插入排序 + 分组跳跃
它不是一次只和前面相邻的元素比,而是先隔着很远比,然后慢慢缩小距离,最后变成普通的插入排序。
为什么需要希尔排序?
简单插入排序有个明显的软肋:当较小的数都堆在数组尾部时,排序效率会很低。因为插入排序每次只能交换相邻元素,要把尾部的小数挪到前面,需要一步一步'冒泡'过去,非常耗时。
看一下插入排序的代码逻辑:
public static void insertionSort(int[] arr) {
int len = arr.length;
for (int i = 1; i < len; i++) {
int j = i;
int temp = arr[j];
while (j > 0 && arr[j - 1] > temp) {
// 如果前一个元素比当前元素大,则将前一个元素向后移动一位
arr[j] = arr[j - 1];
j--;
}
arr[j] = temp;
}
}
而希尔排序通过引入增量(Gap)的概念,允许元素跳跃式移动,让小数能更快地'蹦'到前面,从而解决了这一问题。
核心原理
核心概念:增量(Gap)
希尔排序引入了一个间隔 gap,它不是让元素和相邻的比,而是和相隔 gap 个位置的元素比。
过程分三步:
- 分组:按 gap 把数组分成若干组
- 组内插入排序:对每组分别做插入排序
- 缩小 gap:gap 减半,重复上述过程,直到 gap = 1
当 gap = 1 时,就是普通的插入排序,但此时数组已经基本有序,插入排序会非常快。
代码实现
public static void shellSort {
arr.length;
( n / ; gap > ; gap /= ) {
( gap; i < n; ++i) {
arr[i];
i - gap;
(j >= && arr[j] > key) {
arr[j + gap] = arr[j];
j -= gap;
}
arr[j + gap] = key;
}
}
}


