init commit

This commit is contained in:
2026-08-04 06:57:36 -06:00
commit 0dbc7a78b9
34 changed files with 1686 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="src" path=""/>
<classpathentry kind="output" path=""/>
</classpath>
+2
View File
@@ -0,0 +1,2 @@
/CompareSortingAlgorithms.class
/Driver.class
+8
View File
@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="openjdk-20" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/cs2430-project1.iml" filepath="$PROJECT_DIR$/cs2430-project1.iml" />
</modules>
</component>
</project>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
+28
View File
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>cs2430-project1</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<filteredResources>
<filter>
<id>1695833596179</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
+3
View File
@@ -0,0 +1,3 @@
To run:
Compilation: in the root folder (cs2430-project1), run `javac src/TestDriver.java src/algorithms/*.java src/utils/*.java`
Execute: in the root folder (cs2430-project1), run `java src/TestDriver`
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/results" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
+124
View File
@@ -0,0 +1,124 @@
package src;
import src.algorithms.*;
import src.utils.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
/**
* Compares various sorting algorithms based upon the number of comparisons each algorithm completes.
* Generates and sorts every permutation of numbers from 0 (inclusive) to n (exclusive).
* Current implementation only tests the HeapSort algorithm, but it can be extended to other algorithms.
*
* @author Josh Ashton, Lexus Lindeman, Sean White, Abbas, Culton
*/
public class TestDriver {
/**
* The main driver method to test the sorting algorithms.
* Generates all possible permutations for each test size, then sorts each permutation using a new HeapSort instance.
* After sorting, results (including the number of comparisons) are stored.
* The results are then processed to print out the best, worst, and average cases based on the number of comparisons.
* Results are also saved to a text file in the "results" directory.
*
* @param args Command-line arguments (not used).
*/
public static void main(String[] args) {
int[] testSizes = {4, 6, 8}; // Sizes for which the sorting algorithms will be tested
// Write results to a file in the "results" directory
try {
FileOutputUtil.writeToFile("heapsort.txt", testAlgo(testSizes,0));
System.out.println("Results written to results/heapsort.txt");
FileOutputUtil.writeToFile("mergesort.txt", testAlgo(testSizes,1));
System.out.println("Results written to results/mergesort.txt");
FileOutputUtil.writeToFile("quicksort.txt", testAlgo(testSizes,2));
System.out.println("Results written to results/quicksort.txt");
FileOutputUtil.writeToFile("shakersort.txt", testAlgo(testSizes,3));
System.out.println("Results written to results/shakersort.txt");
} catch (Exception e) {
System.err.println("Error writing to file: " + e.getMessage());
}
}
private static String testAlgo(int[] testSizes, int algo) {
StringBuilder output = new StringBuilder(); // To collect the output for the file
for (int n : testSizes) {
int[][] permutations = PermutationsGenerator.generate(n);
int totalComparisons = 0;
List<Result> results = new ArrayList<>();
for (int[] permutation : permutations) {
int[] copy = Arrays.copyOf(permutation, permutation.length);
int comparisons = 0;
switch (algo) {
case 0:
HeapSort heapSort = new HeapSort(); // Create a new HeapSort instance for each permutation
heapSort.sort(copy);
comparisons = heapSort.getComparisonCount();
totalComparisons += comparisons;
results.add(new Result(permutation, copy, comparisons));
break;
case 1:
MergeSort mergeSort = new MergeSort();
mergeSort.sort(copy);
comparisons = mergeSort.getComparisonCount();
totalComparisons += comparisons;
results.add(new Result(permutation, copy, comparisons));
break;
case 2:
QuickSort quickSort = new QuickSort();
quickSort.sort(copy);
comparisons = quickSort.getComparisonCount();
totalComparisons += comparisons;
results.add(new Result(permutation, copy, comparisons));
break;
case 3:
ShakerSort shakerSort = new ShakerSort();
shakerSort.sort(copy);
comparisons = shakerSort.getComparisonCount();
totalComparisons += comparisons;
results.add(new Result(permutation, copy, comparisons));
break;
}
}
results.sort(Comparator.comparingInt(Result::comparisons));
// Append results to the output StringBuilder
output.append("\n========================================\n");
output.append("RESULTS FOR N = ").append(n).append("\n");
output.append("========================================\n\n");
output.append("Best 10 cases:\n");
output.append("--------------------\n");
for (int i = 0; i < 10; i++) {
output.append("Original: ").append(Arrays.toString(results.get(i).originalArray()))
.append("\nSorted: ").append(Arrays.toString(results.get(i).sortedArray()))
.append("\nComparisons: ").append(results.get(i).comparisons()).append("\n\n");
}
output.append("\nWorst 10 cases:\n");
output.append("--------------------\n");
for (int i = results.size() - 10; i < results.size(); i++) {
output.append("Original: ").append(Arrays.toString(results.get(i).originalArray()))
.append("\nSorted: ").append(Arrays.toString(results.get(i).sortedArray()))
.append("\nComparisons: ").append(results.get(i).comparisons()).append("\n\n");
}
// Print the average comparisons for this test size with two decimal places
output.append("\nAverage comparisons: ").append(String.format("%.2f", totalComparisons / (double) permutations.length)).append("\n");
}
return output.toString();
}
}
+107
View File
@@ -0,0 +1,107 @@
package src.algorithms;
/**
* The `HeapSort` class provides an implementation of the heapsort algorithm.
* Heapsort is a comparison-based sorting algorithm that builds a binary heap
* and then repeatedly extracts the maximum element from the heap to build the
* sorted array.
*
* @author Sean White
*
*<p>
* Usage example:
*<p>
* HeapSort sorter = new HeapSort();
* int[] arr = {4, 10, 3, 5, 1};
* sorter.sort(arr);
* int comparisons = sorter.getComparisonCount();
*/
public class HeapSort {
private int comparisons = 0;
/**
* Sorts an array of integers in ascending order using the HeapSort algorithm.
*
* @param arr The array to be sorted.
*/
public void sort(int[] arr) {
int n = arr.length;
// Build heap (rearrange array)
for (int i = n / 2 - 1; i >= 0; i--) {
comparisons++;
heapify(arr, n, i);
}
// One by one extract an element from heap
for (int i = n - 1; i > 0; i--) {
comparisons++;
// Swap current root with end
swap(arr, 0, i);
// Call max heapify on the reduced heap
heapify(arr, i, 0);
}
}
/**
* Performs the heapify operation on a subtree rooted at a specified index.
*
* @param arr The array in which the heapify operation is performed.
* @param n The size of the heap/subtree.
* @param i The index at which the heapify operation starts.
*/
private void heapify(int[] arr, int n, int i) {
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
// Check if left child exists and is greater than the root
if (left < n) {
comparisons++; // Incrementing the counter for comparison with largest
if (arr[left] > arr[largest]) {
comparisons++;
largest = left;
}
}
// Check if right child exists and is greater than the largest value determined so far
if (right < n) {
comparisons++; // Incrementing the counter for comparison with largest
if (arr[right] > arr[largest]) {
comparisons++;
largest = right;
}
}
// If the largest is not root
if (largest != i) {
comparisons++;
swap(arr, i, largest);
// Recursively heapify the affected sub-tree
heapify(arr, n, largest);
}
}
/**
* Swaps two elements in the array.
*
* @param arr The array in which elements are swapped.
* @param i The index of the first element to be swapped.
* @param j The index of the second element to be swapped.
*/
private void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
/**
* Retrieves the count of comparisons made during the sorting process.
*
* @return The number of comparisons made during sorting.
*/
public int getComparisonCount() {
return comparisons;
}
}
+91
View File
@@ -0,0 +1,91 @@
package src.algorithms;
public class MergeSort {
private int comparisons = 0;
public void sort(int arr[]) {
sort(arr, 0, arr.length - 1);
}
private void sort(int arr[], int l, int r) {
if (l < r) {
comparisons++;
// Find the middle point
int m = l + (r - l) / 2;
// Sort first and second halves
sort(arr, l, m);
sort(arr, m + 1, r);
// Merge the sorted halves
merge(arr, l, m, r);
}
}
private void merge(int arr[], int l, int m, int r) {
// Find sizes of two subarrays to be merged
int n1 = m - l + 1;
int n2 = r - m;
// Create temp arrays
int L[] = new int[n1];
int R[] = new int[n2];
// Copy data to temp arrays
for (int i = 0; i < n1; ++i) {
comparisons++;
L[i] = arr[l + i];
}
for (int j = 0; j < n2; ++j) {
comparisons++;
R[j] = arr[m + 1 + j];
}
// Merge the temp arrays
// Initial indices of first and second subarrays
int i = 0, j = 0;
// Initial index of merged subarray array
int k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
comparisons++;
arr[k] = L[i];
i++;
}
else {
comparisons++;
arr[k] = R[j];
j++;
}
k++;
}
// Copy remaining elements of L[] if any
while (i < n1) {
comparisons++;
arr[k] = L[i];
i++;
k++;
}
// Copy remaining elements of R[] if any
while (j < n2) {
comparisons++;
arr[k] = R[j];
j++;
k++;
}
}
/**
* Retrieves the count of comparisons made during the sorting process.
*
* @return The number of comparisons made during sorting.
*/
public int getComparisonCount() {
return comparisons;
}
}
+90
View File
@@ -0,0 +1,90 @@
package src.algorithms;
import java.util.Random;
public class QuickSort {
private int comparisons = 0;
/**
* Public method for the user to use quick sort.
*
* @param int[] arr, an array containing a permutation.
* @return sorted array
*/
public void sort(int[] arr) {
quickSort(arr, 0, arr.length - 1);
}
/**
* Utility method for quickSort
*
* @param arr
* @param low
* @param high
*/
private void quickSort(int[] arr, int low, int high) {
if (low < high + 1) {
comparisons++;
int p = partition(arr, low, high);
quickSort(arr, low, p - 1);
quickSort(arr, p + 1, high);
}
}
/**
* Swaps two indices of an array
*
* @param arr
* @param index1
* @param index2
*/
private void swap(int[] arr, int index1, int index2) {
int temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
/**
* Returns random pivot index between low and high.
*
* @param low
* @param high
* @return random pivot
*/
private int getPivot(int low, int high) {
Random rand = new Random();
return rand.nextInt((high - low) + 1) + low;
}
/**
* Moves all n < pivot to the left of pivot and all n > pivot
* to the right of pivot, then returns the pivot index.
*
* @param arr
* @param low
* @param high
* @return pivot index
*/
private int partition(int[] arr, int low, int high) {
swap(arr, low, getPivot(low, high));
int border = low + 1;
for (int i = border; i <= high; i++) {
comparisons++;
if (arr[i] < arr[low]) {
comparisons++;
swap(arr, i, border++);
}
}
swap(arr, low, border - 1);
return border - 1;
}
/**
* Retrieves the count of comparisons made during the sorting process.
*
* @return The number of comparisons made during sorting.
*/
public int getComparisonCount() {
return comparisons;
}
}
+48
View File
@@ -0,0 +1,48 @@
package src.algorithms;
public class ShakerSort {
private int comparisons = 0;
/**
* @param int[] arr, an array containing a permutation.
* @return the number of comparisons
*/
public void sort(int[] array) {
for (int i = 0; i < array.length / 2; i++) {
comparisons++;
boolean swapped = false;
for (int j = i; j < array.length - i - 1; j++) {
comparisons++;
if (array[j] > array[j + 1]) {
comparisons++;
int tmp = array[j];
array[j] = array[j + 1];
array[j + 1] = tmp;
swapped = true;
}
}
for (int j = array.length - 2 - i; j > i; j--) {
comparisons++;
if (array[j] < array[j - 1]) {
comparisons++;
int tmp = array[j];
array[j] = array[j - 1];
array[j - 1] = tmp;
swapped = true;
}
}
if (!swapped)
comparisons++;
break;
}
}
/**
* Retrieves the count of comparisons made during the sorting process.
*
* @return The number of comparisons made during sorting.
*/
public int getComparisonCount() {
return comparisons;
}
}
+34
View File
@@ -0,0 +1,34 @@
package src.utils;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/**
* The `FileOutputUtil` class provides utility methods for writing content to files.
* @author Sean White
*/
public class FileOutputUtil {
/**
* Writes the provided content to a specified file inside the "results" directory.
*
* @param filename The name of the file to which the content will be written.
* @param content The content to write to the file.
* @throws IOException If any I/O error occurs.
*/
public static void writeToFile(String filename, String content) throws IOException {
// Ensure the "results" directory exists
File directory = new File("results");
if (!directory.exists()) {
directory.mkdir();
}
// Create the file inside the "results" directory
File file = new File(directory, filename);
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
writer.write(content);
}
}
}
@@ -0,0 +1,94 @@
package src.utils;
import java.util.ArrayList;
import java.util.List;
/**
* Provides functionality to generate all permutations of n integers in lexicographic (dictionary) order.
* The integers in each permutation range from 0 to n-1.
*
* @author Sean White
*
* <p><strong>Usage Example:</strong></p>
* <pre>
* {@code
* PermutationsGenerator generator = new PermutationsGenerator();
* int[][] permutationsFor3 = generator.generate(3);
* for (int[] permutation : permutationsFor3) {
* System.out.println(Arrays.toString(permutation));
* }
* }
* </pre>
*
* The above code will generate and print all permutations for n=3 in lexicographic order:
* <pre>
* [0, 1, 2]
* [0, 2, 1]
* [1, 0, 2]
* [1, 2, 0]
* [2, 0, 1]
* [2, 1, 0]
* </pre>
*/
public class PermutationsGenerator {
/**
* Generates all permutations of n integers in lexicographic order.
*
* @param n The number of integers in each permutation.
* @return A 2D array where each row represents a permutation.
*/
public static int[][] generate(int n) {
List<int[]> results = new ArrayList<>();
// Initialize with the smallest permutation (i.e., [0, 1, 2, ..., n-1])
int[] current = new int[n];
for (int i = 0; i < n; i++) {
current[i] = i;
}
results.add(current.clone());
while (true) {
// Identify the rightmost pair (i, i+1) where current[i] < current[i+1]
int i;
for (i = n - 2; i >= 0; i--) {
if (current[i] < current[i + 1]) {
break;
}
}
// If no such pair exists, we have generated all permutations
if (i == -1) {
break;
}
// Identify the largest index j > i such that current[i] < current[j]
int j;
for (j = n - 1; j > i; j--) {
if (current[i] < current[j]) {
break;
}
}
// Swap elements at indices i and j
int temp = current[i];
current[i] = current[j];
current[j] = temp;
// Reverse the elements after index i to get the next permutation in lexicographic order
int start = i + 1, end = n - 1;
while (start < end) {
temp = current[start];
current[start] = current[end];
current[end] = temp;
start++;
end--;
}
// Store the new permutation
results.add(current.clone());
}
// Convert the list of permutations to a 2D array for the final result
return results.toArray(new int[0][0]);
}
}
+80
View File
@@ -0,0 +1,80 @@
package src.utils;
/**
* Represents the result of sorting a permutation using an algorithm.
* This class encapsulates the original permutation (before sorting),
* the sorted permutation, and the number of comparisons made during sorting.
*
* <p><strong>Usage Example:</strong></p>
* <pre>
* {@code
* int[] original = {3, 1, 2};
* int[] sorted = {1, 2, 3};
* int comparisons = 2; // Typically obtained from the sorting algorithm
*
* Result result = new Result(original, sorted, comparisons);
* System.out.println("Original Array: " + Arrays.toString(result.getOriginalArray()));
* System.out.println("Sorted Array: " + Arrays.toString(result.getSortedArray()));
* System.out.println("Comparisons Made: " + result.getComparisons());
* }
* </pre>
* <p>
* The above code will create a Result object and print:
* <pre>
* Original Array: [3, 1, 2]
* Sorted Array: [1, 2, 3]
* Comparisons Made: 2
* </pre>
*
* @param originalArray The original permutation before sorting
* @param sortedArray The permutation after sorting
* @param comparisons The number of comparisons made during sorting
* @author Sean White
*/
public class Result {
int[] originalArray;
int[] sortedArray;
int comparisons;
/**
* Constructs an immutable Result object with the provided parameters.
*
* @param originalArray The original permutation before sorting
* @param sortedArray The permutation after sorting
* @param comparisons The number of comparisons made during sorting
*/
public Result(int[] originalArray, int[] sortedArray, int comparisons) {
this.originalArray = originalArray.clone(); // Create a defensive copy
this.sortedArray = sortedArray.clone(); // Create a defensive copy
this.comparisons = comparisons;
}
/**
* Retrieves the original permutation before sorting.
*
* @return The original permutation
*/
public int[] originalArray() {
return originalArray.clone(); // Return a defensive copy
}
/**
* Retrieves the permutation after sorting.
*
* @return The sorted permutation
*/
public int[] sortedArray() {
return sortedArray.clone(); // Return a defensive copy
}
/**
* Retrieves the number of comparisons made during sorting.
*
* @return The number of comparisons
*/
public int comparisons() {
return comparisons;
}
}