排序思路
插入排序在数据量小、基本有序的情况下效率比较高。那么数据量大,同时基本无序的情况呢?
这种情况可以进行分组插入排序:根据特定步长将数组分为多个逻辑分组,对每个逻辑分组进行插入排序(每个逻辑分组数据量小,插入排序效率高),然后不断缩小步长,当步长为1时对整个数据进行一次插入排序。(基本有序,比直接使用插入排序效率高)
排序实现
参考大神思路
希尔排序本质上是对插入排序的优化,可以在插入排序的基础上修改。或者把插入排序看成固定步长为1的希尔排序。
要实现希尔排序,可以将插入排序的固定步长由1变为变量gap,在插入排序算法外面套一层循环,不断缩小步长:
public static void sort(int[] a) {
for (int gap = a.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < a.length; i++) {
//获取待排序元素
int inserted = a[i];
int j;
//将已排序队列中大于待排序元素的数值全部后移,同时定位到小于等于待排元素的数组下标
for (j = i - gap; j >= 0 && inserted < a[j]; j -= gap) {
a[j + gap] = a[j];
}
//将待排元素插入到前面定位的下标之后(对于待排序元素全都大于待排序元素的情况也一样适用)
a[j + gap] = inserted;
}
}
}
注意
希尔排序在对逻辑分组进行排序时不是把一个逻辑分组排序完才排下一个分组的,而是从gap位置开始轮流对各个逻辑分组开始插入排序。为什么是从gap位置开始呢?类比插入排序,是从第二位开始排序的,而gap就是第一个逻辑分组的第二位,0到 gap-1 位为各个逻辑分组的第一位!gap+1 为第二个逻辑分组的第二位,gap+2 为第三个逻辑分组的第二位 … …