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

原理:

又称为增量缩小排序。将待排序的数组按增量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) ;
}


 

 

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