標籤:希爾排序 排序演算法
希爾排序又稱“縮小增量排序”,它的基本思想是:先將整個待排記錄序列分割成若干子序列分別進行直接插入排序,待整個序列中的記錄“基本有序”時,再對記錄進行一次直接插入排序。
希爾排序的一個特點是:子序列的構成不是簡單地“逐段分割”,而是將相隔某個“增量”的記錄組成一個子序列。這就使得希爾排序中關鍵字較小的記錄不是一步一步地往前挪動,而是一次按照“增量”的大小跳躍式地往前移,從而使得在進行最後一趟增量為1的插入排序時,序列已基本有序,只要作記錄的少量比較和移動即可完成排序,因此希爾排序的時間複雜度較直接插入排序低。
下面以N=10個記錄為例分析希爾排序的過程,記錄如下:
49 38 65 97 76 13 27 49 55 04
第一趟排序選擇增量為Increment=N/2=5,所以:
49 38 65 97 76 13 27 49 55 04
1A 1B
2A 2B
3A 3B
4A 4B
5A 5B
第二趟排序選擇增量為Increment=Increment/2=2,第一趟排序結果如下:
13 27 49 55 04 49 38 65 97 76
1A 1B 1C 1D 1E
2A 2B 2C 2D 2E
第三趟排序選擇增量為Increment=Increment/2=1,第二趟排序結果如下:
04 27 13 49 38 55 49 65 97 76
第四趟排序選擇增量為Increment=Increment/2=0,即第三趟排序即完成整個排序,結果如下:
04 13 27 38 49 49 55 65 76 97
希爾排序演算法的實現中,一個很重要的問題是增量序列的選擇問題,因為它關係到希爾排序的效能,不同增量序列,效能會相差很遠。通常情況下,第一個增量選為Increment=N/2,後面的增量選為Increment=Increment/2;
範例程式碼1(C語言實現):
/********************************************************************* Author:李冰 date:2014-9-6 Email:[email protected] @array: the pointer to the records @num:the length of the records*********************************************************************/void shellsort(int array[], int num){if(array == NULL || num < 0)return;int i, j, increment;for(increment = num / 2; increment > 0; increment /= 2) //增量序列{ //直接插入排序for(i = 0; i < increment; i++){for(j = i + increment; j < num; j += increment){if(array[j] < array[j - increment]){int tmp = array[j];int k = j - increment;while(k >= 0 && array[k] > tmp){array[k + increment] = array[k];k -= increment;}array[k + increment] = tmp;}}}}}
上面給出的希爾排序是完全按照定義給出的,比較繁瑣,下面給出簡化版本的希爾排序。
範例程式碼2(C語言實現):
/********************************************************************* Author:李冰 date:2014-9-6 Email:[email protected] @array: the pointer to the records @num:the length of the records*********************************************************************/void shellsort(int array[], int num){if(array == NULL || num < 0)return;int i, j, increment;int tmp;for(increment = num / 2; increment > 0; increment /= 2){for(i = increment; i < num; i++){tmp = array[i];for(j = i; j >= increment; j -= increment){if(tmp > array[j - increment])array[j] = array[j - increment];elsebreak;}array[j] = tmp;}}}
總結:
1、希爾排序的增量一般選擇為N/2和Increment/2。
2、希爾排序的最壞情形已耗用時間為O(n^2)。
參考文獻:
1、《資料結構(C語言版)》嚴蔚敏 吳偉東 編著
2、《資料結構與演算法分析——C語言描述》Mark Allen Weiss 著 馮舜璽 譯
3、http://blog.csdn.net/morewindows/article/details/6668714
演算法學習之排序演算法:希爾排序