001package algs21;
002import stdlib.*;
003
004public class XBubble {
005
006        // use natural order and Comparable interface
007        public static <T extends Comparable<? super T>> void sort(T[] a) {
008                int N = a.length;
009                for (int i = 0; i < N; i++) {
010                        for (int j = 1; j < (N - i); j++) {
011                                if (less (a[j], a[j - 1])) {
012                                        exch (a, j, j - 1);
013                                }
014                                assert isSorted (a, N - i - 1, N - 1);
015                        }
016                }
017                assert isSorted (a);
018        }
019
020        /* *********************************************************************
021         *  Helper sorting functions
022         ***********************************************************************/
023
024        // is v < w ?
025        private static <T extends Comparable<? super T>> boolean less(T v, T w) {
026                if (COUNT_OPS) DoublingTest.incOps ();
027                return (v.compareTo(w) < 0);
028        }
029
030        // exchange a[i] and a[j]
031        private static <T> void exch(T[] a, int i, int j) {
032                if (COUNT_OPS) DoublingTest.incOps ();
033                T swap = a[i];
034                a[i] = a[j];
035                a[j] = swap;
036        }
037
038        /* *********************************************************************
039         *  Check if array is sorted - useful for debugging
040         ***********************************************************************/
041        private static <T extends Comparable<? super T>> boolean isSorted(T[] a) {
042                return isSorted(a, 0, a.length - 1);
043        }
044
045        // is the array sorted from a[lo] to a[hi]
046        private static <T extends Comparable<? super T>> boolean isSorted(T[] a, int lo, int hi) {
047                for (int i = lo + 1; i <= hi; i++)
048                        if (less(a[i], a[i-1])) return false;
049                return true;
050        }
051
052        // print array to standard output
053        private static <T> void show(T[] a) {
054                for (T element : a) {
055                        StdOut.println(element);
056                }
057        }
058
059        // test code
060        private static boolean COUNT_OPS = false;
061        public static void main(String[] args) {
062                //StdIn.fromFile ("data/tiny.txt");
063                StdIn.fromFile ("data/words3.txt");
064                String[] a = StdIn.readAllStrings();
065                sort(a);
066                show(a);
067
068                COUNT_OPS = true;
069                DoublingTest.run (2000, 5, N -> ArrayGenerator.integerRandomUnique (N),          (Integer[] x) -> sort (x));
070                DoublingTest.run (2000, 5, N -> ArrayGenerator.integerRandom (N, 2),             (Integer[] x) -> sort (x));
071                DoublingTest.run (2000, 5, N -> ArrayGenerator.integerPartiallySortedUnique (N), (Integer[] x) -> sort (x));
072
073        }
074}