希尔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],并根据比较结果交换元素位置,

  }

}

 

 1 package 排序;
 2 
 3 import java.util.Arrays;
 4 import edu.princeton.cs.algs4.In;
 5 import edu.princeton.cs.algs4.StdOut;
 6 /**
 7  * @author evasean www.cnblogs.com/evasean/
 8  */
 9 @SuppressWarnings("rawtypes")
10 public class Shell排序 {
11     public static void sort(Comparable[] a) {
12         int N = a.length;
13         int h = 1;
14         while (h < N / 3)
15             h = 3 * h + 1;
16         while (h >= 1) {
17             for (int i = h; i < N; i++) { 
18                 for (int j = i; j >= h && less(a[j], a[j - h]); j -= h)
19                     exch(a, j, j - h);
20             }
21             h = h / 3;
22         }
23     }
24 
25     @SuppressWarnings("unchecked")
26     private static boolean less(Comparable v, Comparable w) {
27         return v.compareTo(w) < 0;
28     }
29 
30     private static void exch(Comparable[] a, int i, int j) {
31         Comparable t = a[i];
32         a[i] = a[j];
33         a[j] = t;
34     }
35 
36     private static void show(Comparable[] a) {
37         for (int i = 0; i < a.length; i++)
38             StdOut.print(a[i] + " ");
39         StdOut.println();
40     }
41 
42     public static boolean isSorted(Comparable[] a) {
43         for (int i = 1; i < a.length; i++) {
44             if (less(a[i], a[i - 1]))
45                 return false;
46         }
47         return true;
48     }
49 
50     public static void main(String[] args) {
51         String[] a = new In().readAllStrings();
52         StdOut.println(Arrays.toString(a));
53         sort(a);
54         assert isSorted(a);
55         show(a);
56     }
57 }

 

posted @ 2017-07-25 11:15  evasean  阅读(446)  评论(0编辑  收藏  举报