演算法(3) 希爾排序 java
阿新 • • 發佈:2018-11-14
簡介:希爾排序的實質其實是分組插入排序,再通俗的講就是縮小增量排序,是一種比O(N^2)要好的排序演算法,當然,是比不上O(NlgN)的演算法.
原理:將整個待排元素序列分割成若干個子序列(由相隔某個增量值gap的元素組成),再分別對每個子序列進行快速插入排序,然後減少gap再進行快速插入排序,待gap減少到足夠小,最好是減少到1的時候進行最後一次快速插入排序(gap為1的時候,相當於整個陣列是一個子序列,但是經過前面的若干次重排,整個陣列基本有序,最後進行一次微排即可),此時,整個陣列就是有序的.因為快速插入排序在陣列為基本有序時,效率是很高的,比選擇排序和插入排序要高效的多,當然在gap
原始陣列如下:
增量計算方式gap = length / 2 採用gap = gap / 2
①gap = 10 / 2 = 5
按照相隔為5的原則 將整個陣列按照以下順序分割為了5組,每組分別進行快速插入排序.這樣在這五組中就有序了
②gap = 5 / 2 = 2
按照相隔為2的原則,將整個陣列分割為了2組,再次進行快速插入排序.
③gap = 2 / 2 = 1
即對陣列進行一次快速插入排序即可.結果如下
Java程式碼如下:
經過優化的增量序列如Hibbard經過複雜證明可使得最壞時間複雜度為O(n3/2)public static void sort(int[] arr) { long start = System.currentTimeMillis(); int i, j, gap; for (gap = arr.length / 2; gap > 0; gap = gap / 2) {// 控制分組 for (i = 0; i < gap; i++) {//控制組群排序 for (j = i + gap; j < arr.length; j += gap) {// 控制單組排序 int tmp = arr[j]; int k = j - gap; while (k >= 0 && arr[k] > tmp) { arr[k + gap] = arr[k]; k = k - gap; } arr[k + gap] = tmp; } } } System.out.println("time=" + (System.currentTimeMillis() - start) + "毫秒"); }
public static void betterSort(int[] arr){
long start = System.currentTimeMillis();
int n = arr.length;
// 計算 increment sequence: 1, 4, 13, 40, 121, 364, 1093...
int h = 1;
while (h < n/3) h = 3*h + 1;
while (h >= 1) {
// h-sort the array
for (int i = h; i < n; i++) {
// 對 arr[i], arr[i-h], arr[i-2*h], arr[i-3*h]... 使用插入排序
int e = arr[i];
int j = i;
for ( ; j >= h && e < arr[j - h] ; j -= h)
arr[j] = arr[j-h];
arr[j] = e;
}
h /= 3;
}
System.out.println("betterSort=" + (System.currentTimeMillis() - start) + "毫秒");
}