希尔排序又称缩小增量排序,实质上是分组直接插入排序。为了方便理解,先不讨论如何获得合适的增量数组和整个算法的代码。
1、修改直接插入排序的代码,实现增量为gap的直接插入排序。
/*
* 将数组从start到end中间隔为gap的子序列进行直接插入排序
*/
private static void straightInsertSortWithGap(int[] nums,int start,int end,int gap){
int j,t;
for(int i=start+gap;i<=end;i=i+gap){
t=nums[i];
j=i-gap;
while(j>=start&&t<nums[j]){
nums[j+gap]=nums[j];
j=j-gap;
}
nums[j+gap]=t;
}
}
2、我们先观察如何实现一趟增量为3的直接插入排序。
如有一个数组{12,1,10,3,8,5,6,7,4,9,2,11,0},现在对它进行一次增量为3的分组插入。
顺序\分组 | A{12,3,6,9,0} | B{1,8,7,2} | C{10,5,4,11} |
1 | {12},3 | {1},8 | {10},5 |
2 | {3,12},6 | {1,8},7 | {5,10},4 |
3 | {3,6,12},9 | {1,7,8},2 | {4,5,10},11 |
4 | {3,6,9,12},0 |
3、严格按照希尔排序思想,需要依次排序各组,即执行顺序为A1、A2、A3、A4、B1、B2、B3、C1、C2、C3。
实现代码为:
private static void sortGrouply(int[] nums,int start,int end,int gap){
int i,j,k,t;
for(i=0;i<gap;i++){ //一趟希尔排序会分成gap组,对每一组执行增量为gap的直接插入排序
straightInsertSortWithGap(nums,start+i,end,gap);
}
}
4、其实按照顺序A1、B1、C1、A2、B2、C2、A3、B3、C3、A4执行,结果是一样的。
private static void sortStraightly(int[] nums,int start,int end,int gap){
if(nums==null||nums.length<=end) throw new IllegalArgumentException("输入不合法");
int j,t;
for(int i=start+gap;i<=end;i++){
j=i-gap;
t=nums[i];
while(j>=start&&t<nums[j]){
nums[j+gap]=nums[j];
j-=gap;
}
nums[j+gap]=t;
}
}