希爾排序又叫做遞減增量排序。在這種排序中,我們將設置一個步長(增量),我們在比較數據時根據增量去進行比較,這樣我們的數據會一次性前進很多步,所以希爾排序的效率要比直接插入排序的效率高。
希爾排序的思想就是我們設置一個步長,然后我們根據這個步長進行划分子序列,得到子序列1,子序列2....,然后我們對每個子序列進行直接插入排序,我們也知道當整個數列基本有序的時候使用直接插入排序的效率是非常高的。然后我們縮小步長,則我們划分的子序列的個數越來越少,我們每個子序列中的數據越來越多,則我們基本有序的數據就越來越多,直到我們的增量為1時,我們對整個已經基本有序的序列采用一次直接插入排序,則我們的排序結束。
還是按照往常的習慣,給出圖示
好了,下面直接給出代碼,代碼里面都有詳細的注釋。
1 #include <stdio.h> 2 3 void shellsort(int *arr[],int length); 4 5 int main(int argc, char *argv[]) 6 { 7 int arr[]={ 8 13,14,94,33,82,25,59,94,65,23,45,27,73,25,39 9 }; 10 shellsort(arr,15); 11 int i=0; 12 for(;i<15;i++){ 13 printf("%d ",arr[i]); 14 } 15 return 0; 16 } 17 18 19 /* 20 希爾排序: 21 直接插入排序的改進版,直接插入排序每次只能移動一位,而希爾排序根據特定的步長,移動距離大大增加。 22 希爾排序就是減少增量的排序方法,給出初始設定一個增量,然后根據這個增量將整個序列進行划分,划分成若干個子序列,然后對每 23 個子序列進行直接插入排序。 24 然后再將增量減少,然后再將整個序列划分成若干個子序列,然后在對每個子序列進行直接插入排序,依次類推,直到增量為1時,即 25 對整個序列進行直接插入排序,因為現在的序列已經基本有序,則直接插入排序的效率較高,這樣完成后,我們的整個序列就完全有序。 26 */ 27 28 29 void shellsort(int *arr[],int length){ 30 int gap=length/2; //初始設置增量為數組長度的一半,則我們的每個子序列只有兩個數據 31 32 for(;gap>=1;gap=gap/2){ //我們每次的排序都是根據步長來確定的,而我們的步長每次排序完成后都要改變,直到步長為1,我們這里采用的步長長度每次為一半 33 //在上面設置了步長以后,則我們的待排序數組已經被分成若干個子序列了,則我們對每個子序列進行直接插入排序 34 35 int m; 36 for(m=0;m<gap;m++){ //我們在這里設置一個循環,這個循環我們用於對每個子序列的起點進行設置,每個子序列的起點都是在0到gap之間的 37 //這樣我們就可以把子序列抽離出來,分別是m,m+gap,m+gap+gap...,則我們對這個序列進行直接插入排序 38 int i; 39 int temp; 40 for(i=m+gap;i<length;i=i+gap){ //我們對這個序列進行直接插入排序 41 int j=i; //在這里我們單獨定義一個j出來,不能直接對i進行操作,直接操作i以后,i會發生變化,則我們的遍歷對象不准確了 42 43 while(j!=m){ 44 if(arr[j]<=arr[j-gap]){ //這個子序列相鄰元素之間的距離不再是1,而是gap 45 temp=arr[j-gap]; 46 arr[j-gap]=arr[j]; 47 arr[j]=temp; 48 } 49 j=j-gap; //下標跳轉到下一個元素 50 } 51 } 52 53 } 54 55 } 56 }
ok,以上就是希爾排序的基本原理和代碼實現。
本文屬於博主原創,轉載請標明出處。
http://www.cnblogs.com/WuNaiHuaLuo/