希尔排序
1. 希尔排序的产生
希尔排序是由科学家Donald L.Shell提出的,希尔排序基于插入排序,并添加了一些新的特性,从而大大提高插入排序的执行效率。
2. 插入排序的缺陷,多次移动(参见 插入排序)
假如一个很小的数据在靠右端的位置上。那么要将该数据排序到正确的位置上,则所有的中间数据都需要向右移动一位。
3. 希尔排序的优点
希尔排序通过加大插入排序中元素之间的间隔,并对这些间隔的元素进行插入排序,从而使得数据可以大幅的移动。当完成该间隔的排序后,希尔排序会减少数据的间隔再进行排序。依次进行下去。
4. 间隔的计算
间隔h的初始值为1,通过 h = 3*h+1 来循环计算,直到该间隔大于数组的大小时停止。最大间隔为不大于数组大小的最大值。
(对照下方程序: h<arr.length/3→3*h<arr.length 或者条件可设置为h<=(arr.length-1)/3→h=3*h+1<=arr.length 即 最大间隔为不大于数组大小的最大值。)
5. 间隔减小
可以通过公式 h = (h-1)/3 来计算。
希尔排序
/*
* 希尔排序
*/
public class ShellSort {
/*
* 排序方法
*/
public static void sort(long[] arr){
//初始化一个间隔
int h=1;
//计算最大间隔
while(h<arr.length/3){
h=h*3+1;
}
while(h>0){
//进行插入排序
long tmp=0;
for(int i=h;i<arr.length;i++){
tmp = arr[i];
int j=i;
while(j>h-1 && arr[j-h]>=tmp){
arr[j]=arr[j-h];
j-=h;
}
arr[j]=tmp;
}
//减小间隔
h=(h-1)/3;
}
}
}
测试:
public class TestShellSort {
public static void main(String[] args) {
// TODO Auto-generated method stub
long[] arr=new long[15];
arr[0]=34;
arr[1]=23;
arr[2]=2;
arr[3]=1;
arr[4]=4;
arr[5]=36;
arr[6]=26;
arr[7]=24;
arr[8]=14;
arr[9]=44;
arr[10]=35;
arr[11]=25;
arr[12]=21;
arr[13]=11;
arr[14]=42;
System.out.print("[");
for(long num : arr){
System.out.print(num+" ");
}
System.out.print("]");
System.out.println();
ShellSort.sort(arr);
System.out.print("[");
for(long num : arr){
System.out.print(num+" ");
}
System.out.print("]");
System.out.println();
}
}