/******************************************************************************
* Compilation: javac Shell.java
* Execution: java Shell < input.txt
* Dependencies: StdOut.java StdIn.java
* Data files: http://algs4.cs.princeton.edu/21elementary/tiny.txt
* http://algs4.cs.princeton.edu/21elementary/words3.txt
*
* Sorts a sequence of strings from standard input using shellsort.
*
* Uses increment sequence proposed by Sedgewick and Incerpi.
* The nth element of the sequence is the smallest integer >= 2.5^n
* that is relatively prime to all previous terms in the sequence.
* For example, incs[4] is 41 because 2.5^4 = 39.0625 and 41 is
* the next integer that is relatively prime to 3, 7, and 16.
*
* % more tiny.txt
* S O R T E X A M P L E
*
* % java Shell < tiny.txt
* A E E L M O P R S T X [ one string per line ]
*
* % more words3.txt
* bed bug dad yes zoo ... all bad yet
*
* % java Shell < words3.txt
* all bad bed bug dad ... yes yet zoo [ one string per line ]
*
*
******************************************************************************/
package edu.princeton.cs.algs4;
/**
* The {@code Shell} class provides static methods for sorting an
* array using Shellsort with Knuth's increment sequence (1, 4, 13, 40, ...).
* <p>
* For additional documentation, see <a href="http://algs4.cs.princeton.edu/21elementary">Section 2.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Shell {
private 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);
}
}
assert isHsorted(a, h);
h /= 3;
}
assert isSorted(a);
}
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
private static boolean isSorted(Comparable[] a) {
for (int i = 1; i < a.length; i++)
if (less(a[i], a[i-1])) return false;
return true;
}
private static boolean isHsorted(Comparable[] a, int h) {
for (int i = h; i < a.length; i++)
if (less(a[i], a[i-h])) return false;
return true;
}
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
Shell.sort(a);
show(a);
}
}