/** Demo algorithms from the array algorithm design slides. */ public class Algorithms { /** Yields: index of first occurrence of c in b[0..b.length-1] * OR b.length if none is found */ public static int findFirst(int c, int[] b) { // Store in i the index of the first c in b[0..] int i = 0; // invariant: c is not in b[0..i-1] while (i < b.length && b[i] != c) { i= i + 1; } // post: (b[i] == c OR i == b.length) and c is not in b[0..i-1] return i; } /** Yields: "c is in the array b" * Precondition: b sorted in nondescending order */ public static boolean binarySearch(int c, int[] b) { // Store in i the value BEFORE beginning of range to search int i = 0; // Store in j the end of the range to search int j = b.length; // The middle position of the range int mid = (i+j)/2; // invariant; b[0..i-1] < c, b[j..] >= c while (j > i) { if (b[mid] < c) { i = mid+1; } else { // b[mid] >= c j = mid; } // Compute a new middle. mid = (i+j)/2; } // post: i == j and b[0..i-1] < c and b[j..] >= c return (i < b.length && b[i] == c); } /** Insertion Sort: sorts the array b in n^2 time */ public static void isort(int[] b) { // inv: b[0..i-1] sorted for(int i = 0; i < b.length; i = i+1) { pushDown(b,i); } // post: b[0..b.length-1] sorted } /** Moves the value at position k into its * sorted position in b[0.k-1]. * Precondition: b[0..k-1] is sorted */ public static void pushDown(int[] b, int k) { // inv: b[j..k] is sorted for(int j = k; j > 0; j = j - 1) { if (b[j-1] > b[j]) { swap(b,j-1,j); } } // post: b[0..k] is sorted } /** Selection Sort: sorts the array b in n^2 time */ public static void ssort(int[] b) { // inv: b[0..i-1] sorted for(int i = 0; i < b.length; i = i+1) { int index = minIndex(b,i); swap(b,i,index); } // post: b[0..b.length-1] sorted } /** Yields: the index of the minimum value in b[h..] */ private static int minIndex(int[] b, int h) { int index = h; // inv: index position of min in b[h..i] for(int i = h+1; i < b.length; i = i+1) { if (b[i] < b[index]) { index = i; } } // post: index position of min in b[h..b.length] return index; } /** Quick Sort: sorts the array b in n log n average time */ public static void qsort(int[] b) { qsort(b,0,b.length-1); } /** Quick Sort: sorts the array b[h..k] in n log n average time */ public static void qsort(int[] b, int h, int k) { if (k-h < 1) { return; } int j = partition(b, h, k); // b[h..j-1] <= b[j] <= b[j+1..k] // Sort b[h..j-1] and b[j+1..k] qsort(b, h, j-1); qsort(b, j+1, k); } // NOTE: This uses a DIFFERENT invariant than the lab /** Partitions array b[0..b.length-1] around a pivot x * Precondition: x is in b[0..b.length-1] * Yields: the new location of x */ public static int partition(int[] b, int h, int k) { // position i is end of first paritition range int i = h; // position j is BEFORE beginning of second partition range int j = k; // Find the first element in the array. int x = b[h]; // invariant: b[h..i] < x, b[j+1..k] >= x while (i != j) { if (b[i+1] >= x) { // Move this to the end of the block. swap(b,i+1,j); j = j - 1; } else { // b[i+1] < x swap(b,i,i+1); i = i + 1; } } // post: b[h..i-1] < x, b[i] is x, and b[i+1..k] >= x return i; } /** Dutch National Flag algorithm to arrange the elements of b[h..k] * and produce a Point object Point (i, j) */ public static java.awt.Point dnf(int[] b, int h, int k) { int t= h; int j= k; int i= k+1; // inv: b[h..t-1] < 0, b[t..i-1] unknown, b[i..j] = 0, and b[j+1..k] > 0 while (t < i) { if (b[i-1] < 0) { swap(b,i-1,t); t= t+1; } else if (b[i-1] == 0) { i= i-1; } else { swap(b,i-1,j); i= i-1; j= j-1; } } return new java.awt.Point(i, j); } /** Procedure swaps b[h] and b[k] */ public static void swap (int[] b, int h, int k) { int temp= b[h]; b[h]= b[k]; b[k]= temp; } /** Scrambles the array to resort again */ public static void scramble(int[] b) { // inv: b[0..i-1] is scrambled for(int i = 0; i < b.length; i = i+1) { int size = b.length-i; int pos = (int)(Math.random()*size); swap(b,i,i+pos); } // post: b[0..b.length] is scrambled } }