希爾排序
概括:其實希爾排序就是將數組進行拆分,對分出來的每一個數組進行直接插入排序。
具體講解
設置一個step(步長),step初始值為數組長度 / 2,每隔相同步長的元素被劃分為同一個組,如下圖。
分組
我們可以發現規律,step是多少,那么arr這個數組就會被分成幾組。
之后對每一組進行直接插入排序,不懂直接插入排序請先去參看我寫的直接插入排序的文章:http://www.lxweimin.com/p/553ae4c822e0
將五組插入排序結束之后,arr數組如下圖。
第一次結束
之后改變step的大小,將step再次 / 2,step = 5 / 2 = 2,繼續分組。
第二次分組
分別對兩組進行直接插入排序,結果如下圖
第二次插入結束
最后再將step / 2, step = 2 / 2 = 1。當step等于1時就是最后一次排序,也就只有一組了,就是arr本身。對整體進行一次直接插入排序,完成希爾排序。
希爾排序結束
總結
- 無論step設置為多少,最后一次排序時,step都必須為1,因為最后要對數組整體進行一次直接插入排序。
- 數組分成的組數 == step的值
- 進行希爾排序一定要了解直接插入排序。
總體代碼如下
/**
* Created by ShouJingGuo on 2018/3/14.
* 希爾排序
* 組數也等于step
*/
public class ShellSort {
public static <T> void shellSort(T[] arr, Comparator<T> comparator){
for(int step = arr.length / 2; step > 0; step /= 2){ //步長序列,最后必須為1進行一次,因為要整體進行一次插入排序
for(int i = 0; i < step; i++){ //分別對step數量組進行插入排序
for(int j = step + i; j < arr.length; j += step){ //對其中一組進行排序
T temp = arr[j];
int k = j - step;
while((k >= 0) && (comparator.compare(temp, arr[k]) < 0)){
arr[k+step] = arr[k];
k -= step;
}
arr[k + step] = temp;
}
}
}
}
public static void main(String[] args) {
Integer arr[] = {10,50,24,11,68,20,41,0,24,25,4,7,94,15,5,44,66};
ShellSort.shellSort(arr, new IntegerComparator());
System.out.println(Arrays.toString(arr));
}
}