資料結構系列之希爾排序詳解
阿新 • • 發佈:2018-12-23
基於插入排序的希爾排序Java實現
1、先要搞清楚插入排序的原理
public void InsertSort(int data[]){ //插入排序(升序)
int temp;
int i,j;
for(i=1;i<data.length;i++){
temp=data[i];
for(j=i;j>0&&temp<data[j-1];j--)
data[j]=data[j-1];
data[j]=temp;
}
}
記住一句話:i層迴圈是選元素,j層迴圈將選中的元素放在合理的位置上
2、希爾排序的原理
簡單地說就是先將一個數組劃分成幾個小陣列,然後將每個小陣列的對應元素採用插入排序,再然後就是重新劃分陣列,只不過這次劃分的小陣列的個數比第一次多,再將每個小陣列的對應元素採用插入排序。然後重複這個過程,直至每個小陣列的元素個數為1.
舉例來說,對於6,3,5,9.先採取劃分間隔為2,可將該陣列劃分為兩個小陣列6,3和5,9然後分別對6,5和3,9使用插入排序。此時的陣列變為5,3,6,9,然後再劃分陣列,此時劃分間隔只能為1,故劃分後為5,3,6,9.對這個陣列使用插入排序就完成了希爾排序。
3、希爾排序使用條件
從上述原理來看,使用希爾排序必須保證最後一次劃分間隔為1,否則希爾排序不適用。
public boolean canUseShell(int a[],int groupNumber) { boolean b=false; int m=a.length,n=groupNumber; while(m!=0){ if(m/n==1){ b=true; break; } m=m/n; } return b; }
以上給出了判斷一個數組能否使用希爾排序的方法,其中groupNumbe表示
將陣列分成小陣列的個數。
4、希爾排序的Java實現
public void ShellSort(int a[]){ if(!this.canUseShell(a, 4)){ System.out.print("引數有誤,不能使用希爾排序"); return; } int j; int len = a.length; for(int val=len/4; val>0; val/=4) { //下面是對本次的所有分組做直接插入排序 for(int k=0;k<4;k++) { for(int i=val+k; i<=len-val; i+=val) { int temp = a[i]; for(j=i; j>=val&&temp<a[j-val]; j-=val) { a[j] = a[j-val]; } a[j] = temp; } } } }
注意k層迴圈的作用,若沒有k層,那麼就相當於只對每個小陣列的第一個元素使用了插入排序,但小陣列的其他元素則沒有。
5、測試
public class Sort {
public static void main(String[] args) {
int a[]={2,3,6,-1,0,-4,6,-11,12,-5,21,10,12,45,23,67};
Sort s=new Sort();
s.ShellSort(a);
s.P(a); //列印陣列函式
}
結果為:
陣列為:-11 -5 -4 -1 0 2 3 6 6 10 12 12 21 23 45 67