1. 程式人生 > >資料結構系列之希爾排序詳解

資料結構系列之希爾排序詳解

基於插入排序的希爾排序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.

舉例來說,對於6359.先採取劃分間隔為2,可將該陣列劃分為兩個小陣列6359然後分別對6539使用插入排序。此時的陣列變為5,3,69,然後再劃分陣列,此時劃分間隔只能為1,故劃分後為5369.對這個陣列使用插入排序就完成了希爾排序。

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