diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 7e0010e..4379e7f 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -9,5 +9,8 @@
+
+
+
\ No newline at end of file
diff --git a/src/main/java/algorithms/BubbleSort.java b/src/main/java/algorithms/BubbleSort.java
index 02361d9..78eff60 100644
--- a/src/main/java/algorithms/BubbleSort.java
+++ b/src/main/java/algorithms/BubbleSort.java
@@ -3,25 +3,41 @@
import ui.Utils;
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
public class BubbleSort extends AlgorithmSort {
public BubbleSort(ArrayList array) {
- super(array);
+ super(array);
}
+
@Override
public void sort() {
+ int SLEEP_DURATION = 5;
+
+ if (array.isEmpty()) {
+ System.out.println("Array is empty, nothing to sort.");
+ return;
+ }
+
int n = array.size();
+ Set sortedIndices = new HashSet<>();
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
+ // Visualize the comparison
+ Utils.displayVerticalArray(array, j, j + 1, sortedIndices);
+
if (array.get(j) > array.get(j + 1)) {
- int temp = array.get(j);
- array.set(j, array.get(j + 1));
- array.set(j + 1, temp);
- Utils.printArray(array);
+ // Swap and visualize the result of the selection for this iteration
+ Utils.swapHighlighted(array, j, j + 1, sortedIndices, SLEEP_DURATION);
}
}
+ // Mark the current position as sorted
+ sortedIndices.add(n - i - 1);
}
- }
+ // Final visualization with all elements highlighted in green
+ Utils.displayVerticalArray(array, -1, -1, sortedIndices);
+ }
}
diff --git a/src/main/java/algorithms/InsertionSort.java b/src/main/java/algorithms/InsertionSort.java
index 444a0a8..ceb72d8 100644
--- a/src/main/java/algorithms/InsertionSort.java
+++ b/src/main/java/algorithms/InsertionSort.java
@@ -3,6 +3,8 @@
import ui.Utils;
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
public class InsertionSort extends AlgorithmSort {
@@ -12,23 +14,84 @@ public InsertionSort(ArrayList array) {
@Override
public void sort() {
+ int SLEEP_DURATION = 10;
+ Set sortedIndices = new HashSet<>();
if (array.isEmpty()) {
System.out.println("Array is empty, nothing to sort.");
return;
}
+
int n = array.size();
for (int i = 1; i < n; i++) {
int key = array.get(i);
int j = i - 1;
+ // Highlight the initial key element before shifting
+ highlightInsertion(array, i, -1, -1, sortedIndices, SLEEP_DURATION);
+
+ // Shift elements to the right and highlight each shift
while (j >= 0 && array.get(j) > key) {
array.set(j + 1, array.get(j));
+ highlightInsertion(array, i, j, j + 1, sortedIndices, SLEEP_DURATION);
j = j - 1;
}
+
+ // Place the key in the correct position
array.set(j + 1, key);
+ highlightInsertion(array, -1, j + 1, j + 1, sortedIndices, SLEEP_DURATION);
+
+ // Mark the element as sorted
+ sortedIndices.add(i);
+ }
+
+ // Mark all elements as sorted for the final display
+ Utils.displayVerticalArray(array, -1, -1, sortedIndices);
+ }
+
+ static void highlightInsertion(ArrayList arrayList, int keyIndex, int shiftIndex, int targetIndex, Set sortedIndices, int sleepDuration) {
+ final String RESET = "\033[0m";
+ final String YELLOW = "\033[33m"; // Key element
+ final String RED = "\033[31m"; // Shifted elements
+ final String BLUE = "\033[34m"; // Target position
+ final String GREEN = "\033[32m"; // Sorted elements
- Utils.printArray(array);
+ StringBuilder output = new StringBuilder();
+ int maxHeight = Utils.findMax(arrayList);
+
+ for (int row = maxHeight; row > 0; row--) {
+ output.append("\033[2K"); // Clear the whole line
+
+ for (int col = 0; col < arrayList.size(); col++) {
+ int element = arrayList.get(col);
+
+ if (element >= row) {
+ if (sortedIndices.contains(col)) {
+ output.append(GREEN).append("#").append(RESET);
+ } else if (col == keyIndex) {
+ output.append(YELLOW).append("#").append(RESET);
+ } else if (col == shiftIndex) {
+ output.append(RED).append("#").append(RESET);
+ } else if (col == targetIndex) {
+ output.append(BLUE).append("#").append(RESET);
+ } else {
+ output.append("#");
+ }
+ } else {
+ output.append(" ");
+ }
+ }
+ output.append("\n");
+ }
+
+ System.out.print(output.toString());
+ System.out.print("\033[" + maxHeight + "F");
+
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
}
}
+
}
diff --git a/src/main/java/algorithms/QuickSort.java b/src/main/java/algorithms/QuickSort.java
index cd9cb75..3626524 100644
--- a/src/main/java/algorithms/QuickSort.java
+++ b/src/main/java/algorithms/QuickSort.java
@@ -3,6 +3,8 @@
import ui.Utils;
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
public class QuickSort extends AlgorithmSort {
@@ -12,23 +14,27 @@ public QuickSort(ArrayList array) {
@Override
public void sort() {
- quickSort(0, array.size() - 1);
+ int SLEEP_DURATION = 30;
+
+ Set sortedIndices = new HashSet<>();
+ quickSort(0, array.size() - 1, sortedIndices, SLEEP_DURATION);
+ Utils.displayVerticalArray(array, -1, -1, sortedIndices);
}
- void quickSort(int start, int end) {
+ void quickSort(int start, int end, Set sortedIndices, int sleepDuration) {
if (start < end) {
// pi is the partition return index of pivot
- int pi = partition(start, end);
+ int pi = partition(start, end, sortedIndices, sleepDuration);
// Recursion calls for smaller elements
// and greater or equals elements
- quickSort(start, pi - 1);
- quickSort(pi + 1, end);
+ quickSort(start, pi - 1, sortedIndices, sleepDuration);
+ quickSort(pi + 1, end, sortedIndices, sleepDuration);
}
}
// Partition function
- int partition(int start, int end) {
+ int partition(int start, int end, Set sortedIndices, int sleepDuration) {
int pivot = array.get(end);
// Index of smaller element and indicates
@@ -36,8 +42,9 @@ int partition(int start, int end) {
int pIndex = start;
for (int i = start; i <= end - 1; i++) {
+ Utils.displayVerticalArray(array, i, end, sortedIndices);
if (array.get(i) <= pivot) {
- Utils.swap(array, pIndex, end);
+ Utils.swapHighlighted(array, pIndex, i, sortedIndices, sleepDuration);
pIndex++;
}
}
@@ -48,9 +55,9 @@ int partition(int start, int end) {
// Move pivot after smaller elements and
// return its position
- Utils.swap(array, pIndex, end);
+ Utils.swapHighlighted(array, pIndex, end, sortedIndices, sleepDuration); // Move pivot to correct position
+ sortedIndices.add(pIndex);
return pIndex;
}
-
}
diff --git a/src/main/java/algorithms/SelectionSort.java b/src/main/java/algorithms/SelectionSort.java
index 4469f7f..b188369 100644
--- a/src/main/java/algorithms/SelectionSort.java
+++ b/src/main/java/algorithms/SelectionSort.java
@@ -3,6 +3,8 @@
import ui.Utils;
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
public class SelectionSort extends AlgorithmSort {
@@ -12,6 +14,7 @@ public SelectionSort(ArrayList array) {
@Override
public void sort() {
+ int SLEEP_DURATION = 25;
if (array.isEmpty()) {
System.out.println("Array is empty, nothing to sort.");
@@ -19,22 +22,36 @@ public void sort() {
}
int n = array.size();
+ Set sortedIndices = new HashSet<>();
+
for (int i = 0; i < n - 1; i++) {
int currentMin = i;
for (int j = i + 1; j < n; j++) {
+ // Visualize the comparison
+ Utils.displayVerticalArray(array, i, j, sortedIndices);
+
if (array.get(j) < array.get(currentMin)) {
currentMin = j;
}
}
+ // Swap and visualize the result of the selection for this iteration
if (currentMin != i) {
- int temp = array.get(i);
- array.set(i, array.get(currentMin));
- array.set(currentMin, temp);
+ Utils.swapHighlighted(array, i, currentMin, sortedIndices, SLEEP_DURATION);
}
- Utils.printArray(array);
+ // Mark the current position as sorted
+ sortedIndices.add(i);
+ }
+
+ // Ensure all elements are marked as sorted for the final display
+ for (int i = 0; i < n; i++) {
+ sortedIndices.add(i);
}
+
+ // Final visualization with all elements highlighted in green
+ Utils.displayVerticalArray(array, -1, -1, sortedIndices);
}
}
+
diff --git a/src/main/java/ui/TestUI.java b/src/main/java/ui/TestUI.java
index f2394a3..be6c3b8 100644
--- a/src/main/java/ui/TestUI.java
+++ b/src/main/java/ui/TestUI.java
@@ -1,6 +1,9 @@
package ui;
import algorithms.BubbleSort;
+import algorithms.InsertionSort;
+import algorithms.QuickSort;
+import algorithms.SelectionSort;
import java.util.ArrayList;
import java.util.List;
@@ -10,17 +13,24 @@ public static void start() {
ArrayList list = new ArrayList<>(List.of(
10, 17, 9, 19, 15, 7, 6, 4, 7, 6,
- 6, 20, 17, 6, 5, 8, 8, 5, 17, 18,
- 16, 17, 10, 1, 18, 4, 6, 20, 9, 14,
- 7, 4, 15, 7, 6, 2, 15, 15, 3, 1, 9,
- 2, 19, 8, 16, 14, 19, 5, 20, 9
+ 6, 20, 17, 6, 5, 8, 8, 5, 17, 18,
+ 16, 17, 10, 1, 18, 4, 6, 20, 9, 14,
+ 7, 4, 15, 7, 6, 2, 15, 15, 3, 1, 9,
+ 2, 19, 8, 16, 14, 19, 5, 20, 9
));
BubbleSort bubbleSort = new BubbleSort(list);
+ //bubbleSort.sort();
- bubbleSort.sort();
+ SelectionSort selectionSort = new SelectionSort(list);
+ //selectionSort.sort();
- Utils.printArray(list);
- }
+ QuickSort quickSort = new QuickSort(list);
+ //quickSort.sort();
+
+ InsertionSort insertionSort = new InsertionSort(list);
+ insertionSort.sort();
+
+ }
}
diff --git a/src/main/java/ui/Utils.java b/src/main/java/ui/Utils.java
index 8f7909e..eba8d96 100644
--- a/src/main/java/ui/Utils.java
+++ b/src/main/java/ui/Utils.java
@@ -3,6 +3,7 @@
import io.github.shuoros.jterminal.JTerminal;
import java.util.ArrayList;
+import java.util.Set;
public abstract class Utils {
// change to ### view
@@ -26,7 +27,7 @@ public static void printArray(ArrayList arrayList) {
}
- private static int findMax(ArrayList array) {
+ public static int findMax(ArrayList array) {
int max = 0;
for (var element : array) {
if (element > max) max = element;
@@ -42,5 +43,71 @@ public static void swap(ArrayList arr, int i, int j) {
Utils.printArray(arr);
}
+ public static void swapHighlighted(ArrayList arr, int currentIndex, int targetIndex, Set sortedIndices, int sleepDuration) {
+
+ displayVerticalArray(arr, currentIndex, targetIndex, sortedIndices);
+ try {
+ Thread.sleep(sleepDuration);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+
+ // Perform the swap
+ int temp = arr.get(currentIndex);
+ arr.set(currentIndex, arr.get(targetIndex));
+ arr.set(targetIndex, temp);
+
+ displayVerticalArray(arr, currentIndex, targetIndex, sortedIndices);
+ try {
+ Thread.sleep(sleepDuration);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ public static void displayVerticalArray(ArrayList arrayList, int currentIndex, int targetIndex, Set sortedIndices) {
+ final String RESET = "\033[0m";
+ final String RED = "\033[31m"; // comparison element
+ final String BLUE = "\033[34m"; // target element
+ final String GREEN = "\033[32m"; // sorted elements
+ StringBuilder output = new StringBuilder();
+
+ int maxHeight = findMax(arrayList);
+
+ for (int row = maxHeight; row > 0; row--) {
+ // is used to clear the current line before printing new content for improving animation smoothness
+ output.append("\033[2K"); // Clear the whole line
+ for (int col = 0; col < arrayList.size(); col++) {
+ int element = arrayList.get(col);
+ if (element >= row) {
+ if (sortedIndices.contains(col)) {
+ output.append(GREEN).append("#").append(RESET);
+ } else if (col == currentIndex) {
+ output.append(RED).append("#").append(RESET);
+ } else if (col == targetIndex) {
+ output.append(BLUE).append("#").append(RESET);
+ } else {
+ output.append("#");
+ }
+ } else {
+ output.append(" ");
+ }
+ }
+ output.append("\n");
+ }
+
+ System.out.print(output.toString());
+
+ /*
+ Repositioning the cursor:
+ - makes the visualization smoother;
+ - reduces flicker;
+ - improves performance by avoiding full-screen clearing.
+ */
+ System.out.print("\033[" + maxHeight + "F"); // Move cursor up to the top
+ }
+
+
// fillArrayRandomlyMethod (between 1 and 100 for example)
}
\ No newline at end of file
diff --git a/target/classes/META-INF/MANIFEST.MF b/target/classes/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..37197ef
--- /dev/null
+++ b/target/classes/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: Main
+
diff --git a/target/classes/main/resources/META-INF/MANIFEST.MF b/target/classes/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..37197ef
--- /dev/null
+++ b/target/classes/main/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: Main
+
diff --git a/target/maven-archiver/pom.properties b/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..3d04e33
--- /dev/null
+++ b/target/maven-archiver/pom.properties
@@ -0,0 +1,4 @@
+#Created by Apache Maven 3.9.9
+artifactId=sar
+groupId=sorting.algorithm.visualization
+version=1.0-SNAPSHOT
diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..92f57d8
--- /dev/null
+++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,5 @@
+ui/Utils.class
+Main.class
+ui/TestUI.class
+algorithms/AlgorithmSort.class
+algorithms/BubbleSort.class
diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..97b8af2
--- /dev/null
+++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,5 @@
+/Users/nat-lee/Documents/WORK-CODE/DCI/PROJECTS/sorting-algorithm-visualisation/src/main/java/algorithms/BubbleSort.java
+/Users/nat-lee/Documents/WORK-CODE/DCI/PROJECTS/sorting-algorithm-visualisation/src/main/java/Main.java
+/Users/nat-lee/Documents/WORK-CODE/DCI/PROJECTS/sorting-algorithm-visualisation/src/main/java/ui/TestUI.java
+/Users/nat-lee/Documents/WORK-CODE/DCI/PROJECTS/sorting-algorithm-visualisation/src/main/java/algorithms/AlgorithmSort.java
+/Users/nat-lee/Documents/WORK-CODE/DCI/PROJECTS/sorting-algorithm-visualisation/src/main/java/ui/Utils.java