希爾排序是插入排序的一種擴充和延伸.在希爾排序之前,有必要先說一下插入排序.
插入排序的工作原理:
1.從第2號元素開始掃描,直到最後一個元素.
2.當掃描到i號元素的時候,假定前邊0,1,2,3...i-1號元素都已經有序.用挖坑填數的方法,將A[i]號元素從數組中挖出來,儲存在key中,依次比較A[i-1],A[i-2]....的值,如果都比key大,則後移,直到找到key的最終元素,就把key填進應在的位置.當掃描完成,數組已經有序.
舉個例子:4,7,8,6,9,12.在某一時刻,i指向6,則將j指向i-1,即8.因為8 > 6,則8後挪一位,j繼續前移,7 >6,7繼續前移,4<6,則4後面的位置就是6應在的位置,於是將6填入這個位置即可.重複以上步驟即可完成排序.
代碼:
void InsertSort(int A[],int beg,int end){for(int i=beg+1;i<=end;++i){int key=A[i];int j=i-1;while(j >= beg && A[j] > key){A[j+1]=A[j];--j;}A[j+1]=key;}}
希爾排序實質上是將數組化整為零,先將數組分成n組,對每一組進行插入排序,這裡並不像歸併排序一樣,分開的兩組是一前一後,希爾排序分開的元素中間都隔著一定步長step,實質上,步長為多少,就有多少組.例如:3,4,2,6,7,1,如果step=3,則分開的組為{3,6},{4,7},{2,1}.最後逐漸將step遞減逼向1,當step=1,則數組已經有序.這個比較容易理解,因為步長為1,說明只有一組,對一組數即使直接用插入排序也能排好序.但是這裡用了插入排序的一個很好的性質,那就是,如果數組已經基本有序,那麼插入排序的效率非常高,可以達到o(n).
總結:
希爾排序:
1.將數組劃分為n組,則步長為n
2對每個組排序.
代碼:
#include<iostream>using namespace std;void insertsort(int A[],int beg,int end,int step){for(int i=beg+step;i<=end;i+=step){int key=A[i];int j=i-step;while(j >= beg && A[j] > key){A[j+step]=A[j];j-=step;}A[j+step]=key;}}void shellsort(int A[],int beg,int end){//1.以step分組,步長也為stepfor(int step=(beg+end)/2; step > 0 ; step /=2){//2.對每個組進行排序for(int i=0;i<step;++i)insertsort(A,beg+i,end,step);}}void main(){int A[]={4,6,3,8,9,1,0,24};int len=sizeof(A)/sizeof(A[0]);//insertsort(A,0,len-1);InsertSort(A,0,len-1);//shellsort(A,0,len-1);for(int i=0;i<len;++i)cout<<A[i]<<' ';}