public class Shell {
public static void sort(Comparable[] a){
int N = a.length;
int h = 1;
while(h < N/3){
h =3 * h + 1;
}
while(h >= 1){
for(int i = h;i < a.length;i++){
for(int j = i;j >= h&& less(a[j],a[j-h]);j -= h){
echo(a,j,j-h);
}
}
h = h / 3;
}
}
public static boolean less(Comparable v,Comparable w){
return v.compareTo(w) < 0;
}
public static void echo(Comparable[] a,int i,int j){
Comparable t = a[i];
a[i] = a[j];
a[j] = t;
}
public static void show(Comparable[] a){
for(int i = 0; i < a.length;i++ ){
System.out.print(a[i] + " ");
}
}
public static boolean isSorted(Comparable[] a){
for(int i = 1; i < a.length;i++){
if(less(a[i],a[i-1])) return false;
}
return true;
}
public static Comparable[] Random(int num){
Integer[] a = new Integer[num];
Random rand = new Random();
for(int i = 0;i<num;i++){
a[i] = rand.nextInt(10000);
}
return a;
}
public static void main(String[] args) {
Comparable[] a = Selection.Random(20000);
Long start = System.currentTimeMillis();
sort(a);
Long end = System.currentTimeMillis();
System.out.println("Time is " + (end - start));
/*show(a);*/
}
}
思路:是在插入排序的基础上进行改进,插入排序特点是一步步从右边到左边进行比较交换,但是如果小数在右边的话,意味着要进行多次比较和交换,而希尔排序就是为此改进,交换不相邻的元素对数组进行局部排序,并最终用插入排序将局部有序的数组排序。
说白了,每一次,对间隔长度为h的元素进行排序,然后逐渐缩小h的大小,最终为1,那就是插入排序了。那h值为多少,如代码所示。
希尔排序比插入排序和选择排序都要快。