希尔排序(Shell Sort):是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因DL.Shell于1959年提出而得名。
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,当增量减至1时,整个文件恰被分成一组,算法便终止。
步骤:
将N个元素的数组分成N/2个数字序列,第i个数据和第N/2+i个数据为一组每一组进行插入排序;
将上面排序后的数组分成N/4(取整)个数字序列,第i个数据和第N/4+i,N/2+i,3N/4+i为一组,每一组分别进行插入排序
。。。
直到N/(2^n)取整为1整个数组分到同一个数列,进行最后一次直接插入排序得到一个递增的数组。
java实现代码:
public class ShellSort {
static final int SIZE=10;
public static void main(String[] args) {
int arr[]=new int[SIZE];
for(int i=0;i<arr.length;i++){
arr[i]=(int)(Math.random()*100);
}
System.out.println("排序前的数组:");
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
System.out.println();
shellSort(arr);
System.out.println("希尔排序后的数组:");
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
System.out.println();
}
private static void shellSort(int[] arr) {
int d,i,j,x,y,temp;int n=0;
for(d=arr.length/2;d>0;d=d/2){
for(i=d;i<arr.length;i++){
x=arr[i];//待排数据arr[i]
j=i-d;//待排数据前d位数据arr[j]
while(j>=0&&x<arr[j]){
arr[j+d]=arr[j];
j=j-d;
}
arr[j+d]=x;
}
n++;
System.out.print("第"+n+"步排序后结果为:");
for(y=0;y<arr.length;y++){
System.out.print(arr[y]+" ");
}
System.out.println();
}
}
}
输出为:
排序前的数组:
19 40 71 79 70 3 49 4 30 9
第1步排序后结果为:3 40 4 30 9 19 49 71 79 70
第2步排序后结果为:3 19 4 30 9 40 49 70 79 71
第3步排序后结果为:3 4 9 19 30 40 49 70 71 79
希尔排序后的数组:
3 4 9 19 30 40 49 70 71 79
结果分析:
第一步:这里N=10,10/2=5,所以原数组被分为五组{19 3 }、{40 49}、{71 4}、{79 30}、 {70 9},五组分别进行插入排序,比如:3<19所以arr[0]=3,arr[5]=19注意这里数据3的索引是由5而不是2变成0,数据19的索引是由0变成5而不是2。每组排序完成后原数组变成{3 40 4 30 9 19 49 71 79 70 }
第二步:10/4=2,所以第一步得到的数组被分为两组{3,4,9,49,79}、{40,30,19,71,70},两组分别进行插入排序,得到{3,4,9,49,79}、{19,30,40,70,71}。最终得到数组{3 19 4 30 9 40 49 70 79 71 }
第三步:10/8=1,所以第二步得到的数组被分为一组,就相当于对上面数组进行直接插入排序,由于数组已经有了一定的顺序,所以效率会提高很多。