希尔shell排序(java)

希尔排序是对插入排序的优化,将插入排序的交换步长由1增加到h。

希尔排序的思想是使数组中任意间隔为h的元素有序。步长调幅为h = 3*h + 1, 也就是1,4,13,40,121,364, 1003....这种步长算法是经过论文证明为比较高效的步长。

最开始由最大步长开始排序,最大步长为

while(h < n/3) h = 3*h +1

步长最大时,比较的元素非常少,速度很快

后来步长逐渐缩短,比较的元素越来越多,但是此时元素的有序性也变好了,排序速度还是会很快。

while(h>=1){

for: i from h~n{

for: j from i~h,j = j-h;

比较a[j]和a[j-h],并根据比较结果交换元素位置,

}

}

package 排序;
 
 import java.util.Arrays;
 import edu.princeton.cs.algs4.In;
 import edu.princeton.cs.algs4.StdOut;
 /**
  * @author evasean www.cnblogs.com/evasean/
  */
 @SuppressWarnings("rawtypes")
 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 < N; i++) { 
                 for (int j = i; j >= h && less(a[j], a[j - h]); j -= h)
                     exch(a, j, j - h);
             }
             h = h / 3;
         }
     }
 
     @SuppressWarnings("unchecked")
     private static boolean less(Comparable v, Comparable w) {
         return v.compareTo(w) < 0;
     }
 
     private static void exch(Comparable[] a, int i, int j) {
         Comparable t = a[i];
         a[i] = a[j];
         a[j] = t;
     }
 
     private static void show(Comparable[] a) {
         for (int i = 0; i < a.length; i++)
             StdOut.print(a[i] + " ");
         StdOut.println();
     }
 
     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 void main(String[] args) {
         String[] a = new In().readAllStrings();
         StdOut.println(Arrays.toString(a));
         sort(a);
         assert isSorted(a);
         show(a);
     }
 }

相关推荐