一、介绍
1.希尔排序的思路:希尔排序是插入排序的改进。当输入的数据,顺序是很乱时,插入排序会产生大量的交换元素的操作,比如array[n]的最小的元素在最后,则要经过n-1次交换才能排到第一位,因为插入排序元素只能一位一位地交换。基于插入排序的这个缺点,希尔排序是以一个区间来的交换元素,然后不断缩小区间,直到为1。它的理论是,每次经过一个区间的排序后,元素就会更有序些,所以下一个区间排序时,要交换的元素次数会变少。
2.详细的数据排序交换过程
3.
Proposition.
The number of compares used by shellsort with the increments 1, 4, 13, 40, 121, 364, ... is O(N3/2).
二、代码
1 package algorithms.elementary21; 2 3 import algorithms.util.StdIn; 4 import algorithms.util.StdOut; 5 6 /****************************************************************************** 7 * Compilation: javac Shell.java 8 * Execution: java Shell < input.txt 9 * Dependencies: StdOut.java StdIn.java 10 * Data files: http://algs4.cs.princeton.edu/21sort/tiny.txt 11 * http://algs4.cs.princeton.edu/21sort/words3.txt 12 * 13 * Sorts a sequence of strings from standard input using shellsort. 14 * 15 * Uses increment sequence proposed by Sedgewick and Incerpi. 16 * The nth element of the sequence is the smallest integer >= 2.5^n 17 * that is relatively prime to all previous terms in the sequence. 18 * For example, incs[4] is 41 because 2.5^4 = 39.0625 and 41 is 19 * the next integer that is relatively prime to 3, 7, and 16. 20 * 21 * % more tiny.txt 22 * S O R T E X A M P L E 23 * 24 * % java Shell < tiny.txt 25 * A E E L M O P R S T X [ one string per line ] 26 * 27 * % more words3.txt 28 * bed bug dad yes zoo ... all bad yet 29 * 30 * % java Shell < words3.txt 31 * all bad bed bug dad ... yes yet zoo [ one string per line ] 32 * 33 * 34 ******************************************************************************/ 35 36 /** 37 * The <tt>Shell</tt> class provides static methods for sorting an 38 * array using Shellsort with Knuth's increment sequence (1, 4, 13, 40, ...). 39 * <p> 40 * For additional documentation, see <a href="http://algs4.cs.princeton.edu/21elementary">Section 2.1</a> of 41 * <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 42 * 43 * @author Robert Sedgewick 44 * @author Kevin Wayne 45 */ 46 public class Shell { 47 48 // This class should not be instantiated. 49 private Shell() { } 50 51 /** 52 * Rearranges the array in ascending order, using the natural order. 53 * @param a the array to be sorted 54 */ 55 public static void sort(Comparable[] a) { 56 int N = a.length; 57 58 // 3x+1 increment sequence: 1, 4, 13, 40, 121, 364, 1093, ... 59 int h = 1; 60 while (h < N/3) h = 3*h + 1; 61 62 while (h >= 1) { 63 // h-sort the array 64 for (int i = h; i < N; i++) { 65 for (int j = i; j >= h && less(a[j], a[j-h]); j -= h) { 66 exch(a, j, j-h); 67 } 68 } 69 assert isHsorted(a, h); 70 h /= 3; 71 } 72 assert isSorted(a); 73 } 74 75 76 77 /*************************************************************************** 78 * Helper sorting functions. 79 ***************************************************************************/ 80 81 // is v < w ? 82 private static boolean less(Comparable v, Comparable w) { 83 return v.compareTo(w) < 0; 84 } 85 86 // exchange a[i] and a[j] 87 private static void exch(Object[] a, int i, int j) { 88 Object swap = a[i]; 89 a[i] = a[j]; 90 a[j] = swap; 91 } 92 93 94 /*************************************************************************** 95 * Check if array is sorted - useful for debugging. 96 ***************************************************************************/ 97 private static boolean isSorted(Comparable[] a) { 98 for (int i = 1; i < a.length; i++) 99 if (less(a[i], a[i-1])) return false; 100 return true; 101 } 102 103 // is the array h-sorted? 104 private static boolean isHsorted(Comparable[] a, int h) { 105 for (int i = h; i < a.length; i++) 106 if (less(a[i], a[i-h])) return false; 107 return true; 108 } 109 110 // print array to standard output 111 private static void show(Comparable[] a) { 112 for (int i = 0; i < a.length; i++) { 113 StdOut.println(a[i]); 114 } 115 } 116 117 /** 118 * Reads in a sequence of strings from standard input; Shellsorts them; 119 * and prints them to standard output in ascending order. 120 */ 121 public static void main(String[] args) { 122 String[] a = StdIn.readAllStrings(); 123 Shell.sort(a); 124 show(a); 125 } 126 127 }