希爾排序(Shell Sort)
阿新 • • 發佈:2018-12-24
希爾排序的原理:將待排序資料元素集合按照一定的大小分塊在塊間的資料按照增量(步長)進行直接插入排序,然後根據一定的規則減少步長,再進行一次直接插入排序,直到步長小於1 。
希爾排序需要注意的是最後的增量一定是1 。
下面先給出Java實現程式碼:
程式碼中初始步長為 Math.sqrt(n), n 為帶排資料的長度,內部迴圈:public static void shellSort(int array[]) { if (null == array || 1 >= array.length) return; int step = 0, n = array.length, temp, j; int len = n; do { step = (int) Math.sqrt(n); for (int i = step; i < len; i++) { temp = array[i]; j = i - step; while (j >= 0 && temp < array[j]) { array[j + step] = array[j]; j -= step; } array[j + step] = temp; } n = step; } while (step > 1); }
是對一個特定的步長做一次直接插入排序,當step == 1 時,該待排序集合基本有序所以不用大量移動元素。for (int i = step; i < len; i++) { temp = array[i]; j = i - step; while (j >= 0 && temp < array[j]) { array[j + step] = array[j]; j -= step; } array[j + step] = temp; }
按照上面步驟對下列元素集合做希爾排序的過程如下:
集合R = {37, 40, 38, 42, 461, 5, 7, 9, 12}
第一趟排序取步長 step = 3 ,
途中使用了三種不同的標記,表示了步長中的每一個元素{Ri , Ri+1 , ... Ri+step -1} 。
第二趟排序取步長step = Math.sqrt(3) = 1 ;
得到最後排好序的序列: 5 , 7, 9,12, 37, 38,42,61 。
在上面的例子中比較特殊,之進行了兩趟排序就完成了,而且每趟排序中元素個數都是相同的。而在實際使用中一般step取值為:
step = step/2.2 ;
希爾排序的時間複雜度:O(N^3/2) 到 O(N^7/6) .