I am currently trying to benchmark a Quick Sort algorithm using both Iteration and Recursion. My problem is with my output, my recursive function works properly and sorts the elements. My iterative function is not working properly though. Here are 2 sample output's and my code that I have. You will see that the iterative function works sometimes but not every time. How do I fix this problem?
Output #1
ITERATIVE SORT
464 10 775 896 997
464
10
775
896
997
array index out of bounds
The array was not sorted correctly:
464 at index 0 and 10 at index 1
ITERATIVE SORT
929 225 730 915 991
929
225
730
915
991
array index out of bounds
The array was not sorted correctly:
929 at index 0 and 225 at index 1
ITERATIVE SORT
292 94 382 474 495
292
94
382
474
495
array index out of bounds
The array was not sorted correctly:
292 at index 0 and 94 at index 1
ITERATIVE SORT
207 349 612 719 962
RECURSIVE SORT
207 349 612 719 962
ITERATIVE SORT
655 157 366 806 865
655
157
366
806
865
array index out of bounds
The array was not sorted correctly:
655 at index 0 and 157 at index 1
Data Set Size (n): 5
Iterative Selection Sort Results: Recursive Selection Sort Results:
Average Critical Operation Count: 0 Average Critical Operation Count: 1
Standard Deviation of Count: 0 Standard Deviation of Count: 2
Average Execution Time: 800 Average Execution Time: 160
Standard Deviation of Time: 1600 Standard Deviation of Time: 320
Output #2
ITERATIVE SORT
11 280 305 356 970
RECURSIVE SORT
11 280 305 356 970
ITERATIVE SORT
287 288 459 649 774
RECURSIVE SORT
287 288 459 649 774
ITERATIVE SORT
341 446 569 882 902
RECURSIVE SORT
341 446 569 882 902
ITERATIVE SORT
181 308 382 513 627
RECURSIVE SORT
181 308 382 513 627
ITERATIVE SORT
744 53 917 941 978
744
53
917
941
978
array index out of bounds
The array was not sorted correctly:
744 at index 0 and 53 at index 1
Data Set Size (n): 5
Iterative Selection Sort Results: Recursive Selection Sort Results:
Average Critical Operation Count: 0 Average Critical Operation Count: 10
Standard Deviation of Count: 0 Standard Deviation of Count: 7
Average Execution Time: 0 Average Execution Time: 1400
Standard Deviation of Time: 0 Standard Deviation of Time: 990
SortMain.java
public class SortMain { public static void main(String[] args) throws Exception { int[] sizes = {5}; //, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1500, 2000, 2500, 5000, 7500, 10000, 15000}; new BenchmarkSorts(sizes); } }
BenchmarkSorts.java
import java.util.*; import java.util.stream.*; public class BenchmarkSorts { private final int NUMBER_OF_RUNS = 5; private int[] array; private int iterativeCount = 0; private int recursiveCount = 0; private int iterativeIndex = 0; private int recursiveIndex = 0; private long iterativeTime, recursiveTime; private int [] iterativeCountLog = new int[NUMBER_OF_RUNS]; private int [] recursiveCountLog = new int[NUMBER_OF_RUNS]; private long [] iterativeTimeLog = new long[NUMBER_OF_RUNS]; private long [] recursiveTimeLog = new long[NUMBER_OF_RUNS]; private static QuickSort quickSort = new QuickSort(); public BenchmarkSorts(int[] sizes) { // Creates benchmarks based on the input array size IntStream.range(0, sizes.length).forEach(i -> new BenchmarkSorts(sizes[i])); } private BenchmarkSorts(int n) { // Outer loop 50 times (NUMBER_OF_RUNS) IntStream.range(0, NUMBER_OF_RUNS).forEach(i -> { array = new int[n]; // Inner loop based on the array size (n) IntStream.range(0, n).forEach(j -> { Random random = new Random(); array[j] = random.nextInt(1000); }); // Runs the sort and produces output if an UnsortedException is found try { runSorts(); } catch (UnsortedException e) { System.out.println(e.getMessage()); } }); displayReport(n); } private void runSorts() throws UnsortedException { // Runs iterative sort int returnCount = quickSort.getCount(); long returnTime = quickSort.getTime(); System.out.println("\nITERATIVE SORT"); int[] newArray1 = quickSort.iterativeSort(array, 0, array.length -1); quickSort.printArr(newArray1, newArray1.length); System.out.println("\n"); quickSort.checkSortedArray(newArray1); iterativeCount = iterativeCount + returnCount; iterativeTime = iterativeTime + returnTime; iterativeCountLog[iterativeIndex] = iterativeCount; iterativeTimeLog[iterativeIndex] = iterativeTime; iterativeIndex++; // Runs recursive sort System.out.println("\nRECURSIVE SORT"); int[] newArray2 = quickSort.recursiveSort(array, 0, array.length-1); quickSort.printArr(newArray2, newArray2.length); quickSort.checkSortedArray(newArray2); returnCount = quickSort.getCount(); returnTime = quickSort.getTime(); recursiveCount = recursiveCount + returnCount; recursiveTime = recursiveTime + returnTime; recursiveCountLog[recursiveIndex] = recursiveCount; recursiveTimeLog[recursiveIndex] = recursiveTime; recursiveIndex++; } private void displayReport(int arraySize) { // Sets local variables double iterativeAverageCount = 0; double iterativeAverageTime = 0; double recursiveAverageCount = 0; double recursiveAverageTime = 0; double iterativeVarianceCount = 0; double iterativeVarianceTime = 0; double recursiveVarianceCount = 0; double recursiveVarianceTime = 0; double iterativeSDCount = 0; double iterativeSDTime = 0; double recursiveSDCount = 0; double recursiveSDTime = 0; // Calculates averages for (int i = 0; i < NUMBER_OF_RUNS; i++) { iterativeAverageCount += iterativeCountLog[i]; iterativeAverageTime += iterativeTimeLog[i]; recursiveAverageCount += recursiveCountLog[i]; recursiveAverageTime += recursiveTimeLog[i]; } iterativeAverageCount = iterativeAverageCount / arraySize; iterativeAverageTime = iterativeAverageTime / arraySize; recursiveAverageCount = recursiveAverageCount / arraySize; recursiveAverageTime = recursiveAverageTime / arraySize; // Calculates standard deviations for (int i = 0; i < NUMBER_OF_RUNS; i++) { iterativeVarianceCount += Math.pow(iterativeAverageCount - iterativeCountLog[i], 2); iterativeVarianceTime += Math.pow(iterativeAverageTime - iterativeTimeLog[i], 2); recursiveVarianceCount += Math.pow(recursiveAverageCount - recursiveCountLog[i], 2); recursiveVarianceTime += Math.pow(recursiveAverageTime - recursiveTimeLog[i], 2); } iterativeVarianceCount = iterativeVarianceCount / arraySize; iterativeVarianceTime = iterativeVarianceTime / arraySize; recursiveVarianceCount = recursiveVarianceCount / arraySize; recursiveVarianceTime = recursiveVarianceTime / arraySize; iterativeSDCount = Math.sqrt(iterativeVarianceCount); iterativeSDTime = Math.sqrt(iterativeVarianceTime); recursiveSDCount = Math.sqrt(recursiveVarianceCount); recursiveSDTime = Math.sqrt(recursiveVarianceTime); // Produces output System.out.println("Data Set Size (n): " + arraySize + "\n\tIterative Selection Sort Results: \t\t\t\t\tRecursive Selection Sort Results:" + "\n\tAverage Critical Operation Count: " + Math.round(iterativeAverageCount) + "\t\t\tAverage Critical Operation Count: " + Math.round(recursiveAverageCount) + "\n\tStandard Deviation of Count: " + Math.round(iterativeSDCount) + "\t\t\t\t\tStandard Deviation of Count: " + Math.round(recursiveSDCount) + "\n\tAverage Execution Time: " + Math.round(iterativeAverageTime) + "\t\t\t\t\t\tAverage Execution Time: " + Math.round(recursiveAverageTime) + "\n\tStandard Deviation of Time: " + Math.round(iterativeSDTime) + "\t\t\t\t\t\tStandard Deviation of Time: " + Math.round(recursiveSDTime)); } }
QuickSort.java
public class QuickSort implements SortInterface { private static int count = 0; private static long timeStart = 0; private static long timeEnd = 0; private static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } public static int partition(int[] array, int low, int high) { int pivot = array[high]; int i = (low - 1); for (int j = low; j <= high - 1; j++) { if(array[j] <= pivot) { i++; swap(array, i, j); } } swap(array, i + 1, high); return i + 1; } // function to recursively sort the list public int[] recursiveSort(int[] array, int low, int high) throws UnsortedException { count++; timeStart = System.nanoTime(); int i = partition(array, low, high); if(low < i - 1) { recursiveSort(array, low, i - 1); } if(high > i) { recursiveSort(array, i, high); } timeEnd = System.nanoTime(); return array; } public int[] iterativeSort(int[] array, int low, int high) throws UnsortedException { count++; timeStart = System.nanoTime(); int stack[] = new int[high - 1 + 1]; int top = -1; stack[++top] = low; stack[++top] = high; while (top >= 0) { high = stack[top--]; low = stack[top--]; int pivot = partition(array, low, high); if(pivot - 1 > 1) { stack[++top] = 1; stack[++top] = pivot - 1; } if(pivot + 1 < high) { stack[++top] = pivot + 1; stack[++top] = high; } } timeEnd = System.nanoTime(); return array; } public int[] printArr(int array[], int n) { int i; for (i = 0; i < n; ++i) { System.out.print(array[i] + " "); } return array; } public int getCount() { int result = count; count = 0; return result; } public long getTime() { long time = timeEnd - timeStart; timeEnd = 0; timeStart = 0; return time; } public void checkSortedArray(int[] list) throws UnsortedException { if(list == null || list.length <= 1) { System.out.println("Array is sorted: null or 1 element"); } for (int i = 0; i < list.length - 1; i++) { if (list[i] > list[i + 1]) { try { for (int j = 0; i < list.length - 1; j++) { System.out.println(" " + list[j]); } System.out.println("array is sorted"); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("array index out of bounds"); } throw new UnsortedException("The array was not sorted correctly: \n" + list[i] + " at index " + i + " and " + list[i + 1] + " at index " + (i + 1)); } } } @Override public int[] iterativeSort(int[] array) throws UnsortedException { // TODO Auto-generated method stub return null; } @Override public int[] recursiveSort(int[] array) throws UnsortedException { // TODO Auto-generated method stub return null; } }
SortInterface.java
public interface SortInterface { int[] iterativeSort(int[] array) throws UnsortedException; int[] recursiveSort(int[] array) throws UnsortedException; int getCount(); long getTime(); }
UnsortedException.java
public class UnsortedException extends Exception { private static final long serialVersionUID = 1L; public UnsortedException(String message) { super(message); } }