5.希爾排序
前言
希爾排序也稱爲縮小增量排序,是插入排序算法的一種改進版。
希爾排序應該是最難的排序了
希爾排序的誕生是由於插入排序在處理大規模數組的時候會遇到需要移動太多元素的問題。
實現思路
希爾排序的思想是將一個大的數組“分而治之”,將一個大的數組劃分爲若干個小的數組。以 gap (間隔)來劃分,比如數組 [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ,如果以間隔 gap = 2劃分,可以劃分爲 [ 1 , 3 , 5 , 7 ] 和 [ 2 , 4 , 6 , 8 ] 兩個數組;對應的,若間隔 gap = 3 ,則劃分的數組爲: [ 1 , 4 , 7 ] 、 [ 2, 5 , 8 ] 、 [ 3 , 6 ] 。然後分別對這些子數組進行正統的插入排序,排序好後將數組回收到大數組裏,再減少間隔 gap 的值重複進行之前的操作,直到間隔 gap = 1時,此時子數組只有一個,就是整個大數組,此時其實都快排好序了,在對這唯一的子數組進行最後一次插入排序的時候,移動的數會很少很少,從而解決了插入排序在處理大規模數組時較多移動次數的問題。
模擬走位
初始數組:[ 26 , 19 , 7 , 37 , 27 , 57 , 67 , 99 , 87 , 17 ]
第一次:
初次計算間隔 gap = 10 / 2 = 5
( 26 走五步是57,以此類推 )
26 19 7 37 27
57 67 99 87 17
進行列排序( 比如,26和57是一列,以此類推 )
26 19 7 37 17
57 67 99 87 27
按行取回放入大數組裏:[ 26 , 19 , 7 , 37 , 17 , 57 , 67 , 99 , 87, 27 ]
第二次:
gap = 5 / 2 = 2
( 26 走兩步是7,以此類推 )
26 19
7 37
17 57
67 99
87 27
進行列排序( 比如,26、7、17、67、87 是一列,以此類推 )
7 19
17 27
26 37
67 57
87 99
按行取回放入大數組裏:[ 7 , 19 , 17 , 27 , 26 , 37 , 67 , 57 , 87 , 99 ]
第三次:
gap = 2 / 2 = 1
( 7 開始一步一步走 )
7
19
17
27
26
37
67
57
87
99
進行列排序
7
17
19
26
27
37
57
67
87
99
按行取回放入大數組裏:[ 7 , 17 , 19 , 26 , 27 , 37 , 57 , 67 , 87 , 99 ]
總結:其實很有節奏和規律,不算複雜。
實現代碼
public <T extends Comparable<T>> void shellSorting(T[] array) {
int len = array.length;
int i, j, gap;
// 逐漸減小步長
for (gap = len / 2; gap > 0; gap /= 2) {
// 佈置行數據
for (i = 0; i < gap; i++) {
// 佈置列數據
for (j = gap; j < len; j += gap) {
if (array[j - gap + i].compareTo(array[j + i]) > 0) {
T temp = array[j - gap + i];
array[j - gap + i] = array[j + i];
array[j + i] = temp;
}
}
}
}
}
運行
public static void main(String args[]) {
Integer[] object = {26, 19, 7, 37, 27, 57, 67, 99, 87, 17};
System.out.println("\n希爾排序\n");
ShellSort shellSorting = new ShellSort();
shellSorting.shellSorting(object);
System.out.println("\n希爾排序\n");
for (int i : object) {
System.out.print(i + " ");
}
}