希尔排序是对插入排序的优化,将插入排序的交换步长由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 }