常用排序算法之希爾排序法

原理:

又稱爲增量縮小排序。將待排序的數組按增量n劃分成n組(把它們當成一組,但不實際分組,只是當成一組來看,只是爲了說明分組關係),每組元素的下標相隔n,使用插入排序法對每一小組進行排序,然後縮小增量n,重新劃分小組進行排序,直到n爲1時對整個數組進行插入排序,排序過程結束。

要點:

1.增量的選擇,一般會選擇array.length / 2作爲初始增量,之後n/=2 ;

2.增量n=1時對整個數組進行插入排序結束。

講解:

設數組爲array[0...len-1],數組長度爲len

1. 初始時,增量n=len/2;

2. 將數組劃分成n組,如array1[0,n,2n]、array2[1,n+1,2n+1]、array3[2,n+2,2n+2]...arrayn[n-1,n+n-1,2n+n-1];

3. 對每個小組進行插入排序,n=n/2;

4.重複第2步,直到n=1時排序結束;

 

實例:

現有數組[6, 2, 1, 7, 9, 4, 3, 8, 5, 10],要求對其進行升序排序。

初始時:n=len/2=5 ;

②根據增量對該數組進行分組得:[6,4],[2,3],[1,8],[7,5],[9,10],如圖1.1;

③對每個小組進行插入排序得:[4,2,1,5,9,6,3,8,7,10],如圖1.2

④增量n=n/2=2,對數組繼續進行分組得:[4,1,9,3,7],[2,5,6,8,10],如圖1.3;

⑤對每個小組進行插入排序得:[1,2,3,5,4,6,7,8,9,10],如圖1.4;

⑥增量n=n/2=1,對數組進行分組,即還是原來的數組:[1,2,3,5,4,6,7,8,9,10],如圖1.5;

⑦對分組進行插入排序得:[1,2,3,4,5,6,7,8,9,10],如圖1.6;

⑧增量n=1,排序結束。 


程序:

/**
 * 希爾排序法(基於插入排序)
 * @param array
 */
public static void shellSort(int[] array){
	int gap ;	//增量
	int i,j,tmp ;
	for(gap=array.length/2;gap>0;gap/=2){
		for(i=gap;i<array.length;i++){
			tmp = array[i] ;
			for(j=i;j>=gap;j-=gap){	//基於快速排序
				if(array[j-gap]>array[j]){//當array[high] < array[high+gap],前面的值都比array[high+gap]小,不需再執行內循環,還可以優化
					tmp = array[j] ;
					array[j] = array[j-gap] ;
					array[j-gap] = tmp ;
				}
			}
		}
	}
}

/**
 * 希爾排序法優化(基於插入排序)
 * @param array
 */
public static void shellSort2(int[] array){
	int gap ;	//增量
	int i,j,tmp ;
	for(gap=array.length/2;gap>0;gap/=2){
		for(i=gap;i<array.length;i++){
			tmp = array[i] ;
			for(j=i;j>=gap&&array[j-gap]>tmp;j-=gap){
				array[j] = array[j-gap] ;//大的值往後移
			}
			array[j] = tmp ;
		}
	}
	print(array) ;
}


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章