import Utilities.*; import Synchronization.*; class QuickSort extends MyObject implements Runnable { private static final int MAX_PER_LINE = 15; private static int N = 15; private static int RANGE = 1000; private static boolean debug = false; private static int[] nums = null; private int left = -1, right = -1; private QuickSort(int left, int right) { super("QuickSort: " + left + " to " + right); this.left = left; this.right = right; } private static Thread QuickSortThread(int left, int right) { QuickSort qs = new QuickSort(left, right); Thread qst = new Thread(qs); qst.start(); return qst; } public void run() { int pivot = nums[left]; int l = left, r = right; Thread qsl = null, qsr = null; // for the "recursive" threads if (debug) System.out.println("*DEBUG* age()=" + age() + ", " + getName()); if (right-left <= 0) { // not supposed to happen System.err.println("right-left<=0, error!"); return; } boolean done = false; while (!done) { if (nums[l+1] > pivot) { // needs to be moved to other end of nums while (r > l+1 && nums[r] > pivot) { r--; // find one to swap } if (r > l+1) { l++; int temp = nums[r]; // swap nums[r] = nums[l]; nums[l] = temp; done = l >= r-1; } else done = true; // if can't find one to swap, then } else { l++; done = l >= r; // need not be moved to other end } } // when this loop finishes, nums[left] is the pivot, // nums[left:l] <= pivot and nums[l+1,right] > pivot // // [pivot, <= | > ] // ^ ^ ^ ^ // | | | | // left l r right // | | | | // v v v v // [<=, pivot | > ] int temp = nums[left]; // swap nums[left] = nums[l]; nums[l] = temp; // nums[left,l-1] <= pivot, // nums[l] == pivot, and // nums[l+1,right] > pivot // start the "recursive" threads, if any if (right-(l+1) > 0) qsr = QuickSortThread(l+1, right); // else nums[l+1:right] is singleton and already sorted // nums[l] = pivot is singleton so sorted if ((l-1)-left > 0) qsl = QuickSortThread(left, l-1); // else nums[left:l-1] is singleton and already sorted try { // and wait for them to finish if (qsl != null) qsl.join(); if (qsr != null) qsr.join(); } catch (InterruptedException e) { System.err.println("QuickSort Exception " + e); } } private static void printArray(int[] a) { int count = 0; for (int i = 0; i < a.length; i++) { System.out.print(" " + a[i]); count++; if (count % MAX_PER_LINE == 0) System.out.print("\n"); } if (count % MAX_PER_LINE != 0) System.out.print("\n"); } public static void main(String[] args) { // parse command line options, if any, to override defaults GetOpt go = new GetOpt(args, "Udn:r:"); go.optErr = false; String usage = "Usage: -d -n N -r RANGE" + " nums[i] in [1,RANGE] for i=0,1,...,N"; int ch = -1; while ((ch = go.getopt()) != go.optEOF) { if ((char)ch == 'U') { System.out.println(usage); System.exit(0); } else if ((char)ch == 'd') { debug = true; // go.optErr = true; } else if ((char)ch == 'n') { N = go.processArg(go.optArgGet(), N); if (N < 2) { System.err.println("QuickSort, N < 2"); System.exit(1); } } else if ((char)ch == 'r') { RANGE = go.processArg(go.optArgGet(), RANGE); if (RANGE < 10) { System.err.println("QuickSort, RANGE < 10"); System.exit(1); } } else { System.err.println(usage); System.exit(1); } } System.out.println("Quick sorting " + N + " integers between -" + RANGE + " and " + RANGE + " (debug=" + debug + ")\n" + " (or get the integers from the command line)"); nums = new int[N]; int argNum = go.optIndexGet(); for (int i = 0; i < N; i++) { nums[i] = (int)random(-RANGE, RANGE); nums[i] = go.tryArg(argNum++, nums[i]); } System.out.println("Original numbers:"); printArray(nums); Thread qst = QuickSortThread(0, N-1); // start up the first thread try { // and wait for it to finish qst.join(); } catch (InterruptedException e) { System.err.println("QuickSort Exception " + e); } System.out.println("Sorted numbers:"); printArray(nums); System.out.println("age()=" + age() + ", done"); System.exit(0); } } /* ............... Example compile and run(s) D:\>javac qsrt.java D:\>java QuickSort -d Quick sorting 15 integers between -1000 and 1000 (debug=true) (or get the integers from the command line) Original numbers: 375 -376 383 6 -34 -164 -245 -465 704 -52 -420 -437 815 -607 503 *DEBUG* age()=0, QuickSort: 0 to 14 *DEBUG* age()=50, QuickSort: 11 to 14 *DEBUG* age()=50, QuickSort: 0 to 9 *DEBUG* age()=110, QuickSort: 11 to 12 *DEBUG* age()=110, QuickSort: 4 to 9 *DEBUG* age()=110, QuickSort: 0 to 2 *DEBUG* age()=110, QuickSort: 4 to 7 *DEBUG* age()=160, QuickSort: 5 to 7 Sorted numbers: -607 -465 -437 -420 -376 -245 -164 -52 -34 6 375 383 503 704 815 age()=220, done ... end of example run(s) */