/* Java class that illustrates the recursive QuickSort algorithm. ** (limited to sorting arrays containing values of type int[]). ** ** Author: R. McCloskey ** Date: November 2023 */ public class RecursiveQuickSort { private static int depth = -1; /* Rearranges the elements of the given array to be in ascending order, ** employing Tony Hoare's recursive QuickSort algorithm. */ public static void quickSort(int[] a) { quickSortNarrated(a, 0, a.length); // sorts and narrates // quickSort(a, 0, a.length); // sorts without narration } /* Rearrange the elements in the specified array segment (i.e., a[low..high)) ** so that they are in ascending order, employing Tony Hoare's recursive ** QuickSort algorithm. ** pre: 0 <= low <= high <= a.length */ public static void quickSort(int[] a, int low, int high) { if (high - low < 2) { // do nothing with a segment of length <= 1 } else { // partition a[low..high) and record where the pivot ended up int r = partition(a, low, high); quickSort(a, low, r); // sort the RED (<-pivot) segment quickSort(a, r+1, high); // sort the BLUE (>=-pivot) segment // (excluding location r, which } // contains the pivot) } /* Rearrange the elements in the specified array segment (i.e., a[low..high)) ** so that they are in ascending order, employing Tony Hoare's recursive ** QuickSort algorithm. This version outputs a narration of its execution. ** pre: 0 <= low <= high <= a.length */ public static void quickSortNarrated(int[] a, int low, int high) { depth++; printMessage("Received "); printArraySeg(a, low, high); if (high - low < 2) { // do nothing printMessage("Nothing need be done!\n"); } else { // partition a[low..high) and record where the pivot ended up int r = partition(a, low, high); printMessage("Red (<-pivot) segment is "); printArraySeg(a, low, r); printMessage("Blue (>=-pivot) segment is "); printArraySeg(a, r, high); quickSortNarrated(a, low, r); // sort the RED (<-pivot) segment quickSortNarrated(a, r+1, high); // sort the BLUE (>=-pivot) segment // (excluding location r, which // contains the pivot) printMessage("After recursive call: "); printArraySeg(a, low, high); } depth--; } /* Rearranges the elements of the given array segment (i.e., b[low..high)) ** and returns a value m satisfying these conditions: ** (1) low <= m < high ** (2) All elements in b[low..m) are < b[m] ** (3) All elements in b[m..high) are >= b[m] */ public static int partition(int[] b, int low, int high) { // arbitrarily choose the pivot to be the value at location high-1 // and leave it there while partitioning b[low..high-1) int pivot = b[high-1]; int i = low; int m = high-1; while (i != m) { if (b[i] < pivot) { i = i+1; } else if (b[m-1] >= pivot) { m = m-1; } else { swap(b, i, m-1); i = i + 1; m = m - 1; } } // Now place the pivot at the beginning of the >=-pivot segment. swap(b, m, high-1); return m; } /* Swaps the values at the specified locations within the specified array. */ private static void swap(int[] b, int j, int k) { int temp = b[j]; b[j] = b[k]; b[k] = temp; } //--------------------------------------------------------------- /* For testing purposes. */ public static void main(String[] args) { int[] ary = new int[] { 23, 5, -6, 14, 0, 31, 18, 12, 7, 3, 20, 9 }; quickSort(ary); } /* Displays the contents of the specified array segment, also ** identifying its boundaries. */ private static void printArraySeg(int[] ary, int low, int high) { System.out.print("low:" + low + "; high:" + high); System.out.print(": ["); for (int i = low; i != high; i++) { System.out.printf("%d ", ary[i]); } System.out.println(']'); } /* Prints the specified String, indented in accord with the value ** of 'depth'. */ private static void printMessage(String s) { printSpaces(3*depth); System.out.print(s); } /* Prints the specified # of spaces. */ private static void printSpaces(int n) { for (int i=0; i != n; i++) { System.out.print(' '); } } }