Skip to content

Commit 0706312

Browse files
committedNov 5, 2022
Added Sorting algorithms
0 parents  commit 0706312

34 files changed

+1193
-0
lines changed
 

‎.idea/.gitignore

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎.idea/misc.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎.idea/modules.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎.idea/uiDesigner.xml

+124
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<module type="JAVA_MODULE" version="4">
3+
<component name="NewModuleRootManager" inherit-compiler-output="true">
4+
<exclude-output />
5+
<content url="file://$MODULE_DIR$">
6+
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
7+
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
8+
</content>
9+
<orderEntry type="inheritedJdk" />
10+
<orderEntry type="sourceFolder" forTests="false" />
11+
</component>
12+
</module>
Loading
Binary file not shown.

‎resources/logo.png

8.79 KB
Loading

‎src/sortvisualiser/MainApp.java

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package sortvisualiser;
2+
3+
import sortvisualiser.screens.MainMenuScreen;
4+
import sortvisualiser.screens.Screen;
5+
import java.util.ArrayList;
6+
import javax.swing.JFrame;
7+
import javax.swing.SwingUtilities;
8+
9+
public class MainApp {
10+
private final JFrame window;
11+
12+
public static final int WIN_WIDTH = 1280;
13+
public static final int WIN_HEIGHT = 720;
14+
15+
private final ArrayList<Screen> screens;
16+
17+
public MainApp() {
18+
screens = new ArrayList<>();
19+
window = new JFrame ("Sort visualiser");
20+
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
21+
window.setVisible(true);
22+
}
23+
24+
public Screen getCurrentScreen() {
25+
return screens.get(screens.size() - 1);
26+
}
27+
28+
public void pushScreen(Screen screen) {
29+
if (!screens.isEmpty()) {
30+
window.remove(getCurrentScreen());
31+
}
32+
screens.add(screen);
33+
window.setContentPane(screen);
34+
window.validate();
35+
screen.onOpen();
36+
}
37+
38+
public void popScreen() {
39+
if (!screens.isEmpty()) {
40+
Screen prev = getCurrentScreen();
41+
screens.remove(prev);
42+
window.remove(prev);
43+
if (!screens.isEmpty()) {
44+
Screen current = getCurrentScreen();
45+
window.setContentPane(current);
46+
window.validate();
47+
current.onOpen();
48+
}
49+
else {
50+
window.dispose();
51+
}
52+
}
53+
}
54+
55+
public void start() {
56+
pushScreen(new MainMenuScreen(this));
57+
window.pack();
58+
}
59+
60+
public static void main(String... args) {
61+
System.setProperty("sun.java2d.opengl", "true");
62+
SwingUtilities.invokeLater(() -> {
63+
new MainApp().start();
64+
});
65+
}
66+
}

‎src/sortvisualiser/SortArray.java

+264
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
package sortvisualiser;
2+
3+
import java.awt.AlphaComposite;
4+
import java.awt.BorderLayout;
5+
import java.awt.Color;
6+
import java.awt.Dimension;
7+
import java.awt.Font;
8+
import java.awt.Graphics;
9+
import java.awt.Graphics2D;
10+
import java.awt.RenderingHints;
11+
import java.awt.image.BufferedImage;
12+
import java.util.Arrays;
13+
import java.util.HashMap;
14+
import java.util.Map;
15+
import java.util.Random;
16+
17+
import javax.swing.JPanel;
18+
import javax.swing.JSpinner;
19+
import javax.swing.SpinnerNumberModel;
20+
21+
import sortvisualiser.algorithms.ISortAlgorithm;
22+
23+
/**
24+
* The array that can be sorted
25+
*
26+
* @author mhops
27+
*/
28+
public class SortArray extends JPanel {
29+
public static final int DEFAULT_WIN_WIDTH = 1280;
30+
public static final int DEFAULT_WIN_HEIGHT = 720;
31+
private static final int DEFAULT_BAR_WIDTH = 5;
32+
/**
33+
* This is the percent of the panel the bars will consume.
34+
* Based on the original 256 bars each being 2x their height
35+
* and 720px window height, or 512/720
36+
*/
37+
private static final double BAR_HEIGHT_PERCENT = 512.0/720.0;
38+
private static final int NUM_BARS = DEFAULT_WIN_WIDTH / DEFAULT_BAR_WIDTH;
39+
40+
private final int[] array;
41+
private final int[] barColours;
42+
private String algorithmName = "";
43+
44+
private String tandComplexity = " ";
45+
private ISortAlgorithm algorithm;
46+
private long algorithmDelay = 0;
47+
48+
// private final MidiSoundPlayer player;
49+
private final JSpinner spinner;
50+
// private final boolean playSounds;
51+
52+
private int arrayChanges = 0; // Number of changes to the array the current algorithm has taken so far
53+
54+
public SortArray() {
55+
setBackground(Color.DARK_GRAY);
56+
array = new int[NUM_BARS];
57+
barColours = new int[NUM_BARS];
58+
for (int i = 0; i < NUM_BARS; i++) {
59+
array[i] = i;
60+
barColours[i] = 0;
61+
}
62+
// player = new MidiSoundPlayer(NUM_BARS);
63+
// this.playSounds = playSounds;
64+
spinner = new JSpinner(new SpinnerNumberModel(1, 1, 1000, 1));
65+
spinner.addChangeListener((event) -> {
66+
algorithmDelay = (Integer) spinner.getValue();
67+
algorithm.setDelay(algorithmDelay);
68+
});
69+
add(spinner,BorderLayout.LINE_START);
70+
}
71+
72+
public int arraySize() {
73+
return array.length;
74+
}
75+
76+
public int getValue(int index) {
77+
return array[index];
78+
}
79+
80+
/**
81+
* Gets the max value of the array or Integer.MIN_VALUE if there isn't one.
82+
* @return the max value or Integer.MIN_VALUE.
83+
*/
84+
public int getMaxValue() {
85+
return Arrays.stream(array).max().orElse(Integer.MIN_VALUE);
86+
}
87+
88+
private void finaliseUpdate(int value, long millisecondDelay, boolean isStep) {
89+
repaint();
90+
try {
91+
Thread.sleep(millisecondDelay);
92+
} catch (InterruptedException ex) {
93+
Thread.currentThread().interrupt();
94+
}
95+
// if (playSounds) {
96+
// player.makeSound(value);
97+
// }
98+
if (isStep)
99+
arrayChanges++;
100+
}
101+
102+
public void swap(int firstIndex, int secondIndex, long millisecondDelay, boolean isStep) {
103+
int temp = array[firstIndex];
104+
array[firstIndex] = array[secondIndex];
105+
array[secondIndex] = temp;
106+
107+
barColours[firstIndex] = 100;
108+
barColours[secondIndex] = 100;
109+
110+
finaliseUpdate((array[firstIndex] + array[secondIndex]) / 2, millisecondDelay, isStep);
111+
}
112+
113+
public void updateSingle(int index, int value, long millisecondDelay, boolean isStep) {
114+
array[index] = value;
115+
barColours[index] = 100;
116+
117+
118+
finaliseUpdate(value, millisecondDelay, isStep);
119+
repaint();
120+
}
121+
122+
public void shuffle() {
123+
arrayChanges = 0;
124+
Random rng = new Random();
125+
for (int i = 0; i < arraySize(); i++) {
126+
int swapWithIndex = rng.nextInt(arraySize() - 1);
127+
swap(i, swapWithIndex, 5, false);
128+
}
129+
arrayChanges = 0;
130+
}
131+
132+
public void highlightArray() {
133+
for (int i = 0; i < arraySize(); i++) {
134+
updateSingle(i, getValue(i), 5, false);
135+
}
136+
}
137+
138+
/**
139+
* Gets the canvas size
140+
*
141+
* @return size
142+
*/
143+
@Override
144+
public Dimension getPreferredSize() {
145+
return new Dimension(DEFAULT_WIN_WIDTH, DEFAULT_WIN_HEIGHT);
146+
}
147+
148+
public void resetColours() {
149+
for (int i = 0; i < NUM_BARS; i++) {
150+
barColours[i] = 0;
151+
}
152+
repaint();
153+
}
154+
155+
@Override
156+
public void paintComponent(Graphics g) {
157+
super.paintComponent(g);
158+
Graphics2D panelGraphics = (Graphics2D) g.create();
159+
160+
try
161+
{
162+
Map<RenderingHints.Key, Object> renderingHints = new HashMap<>();
163+
renderingHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
164+
panelGraphics.addRenderingHints(renderingHints);
165+
panelGraphics.setColor(Color.WHITE);
166+
panelGraphics.setFont(new Font("Monospaced", Font.BOLD, 20));
167+
panelGraphics.drawString(" Current algorithm: " + algorithmName, 10, 30);
168+
panelGraphics.drawString(" Time Complexity & Space Complexity: " + tandComplexity, 10, 55);
169+
panelGraphics.drawString("Current step delay: " + algorithmDelay + "ms", 10, 80);
170+
// panelGraphics.drawString(" Array Changes: " + arrayChanges, 10, 105);
171+
172+
drawBars(panelGraphics);
173+
} finally {
174+
panelGraphics.dispose();
175+
}
176+
}
177+
178+
private void drawBars(Graphics2D panelGraphics)
179+
{
180+
int barWidth = getWidth() / NUM_BARS;
181+
int bufferedImageWidth = barWidth * NUM_BARS;
182+
int bufferedImageHeight = getHeight();
183+
184+
if(bufferedImageHeight > 0 && bufferedImageWidth > 0) {
185+
if(bufferedImageWidth < 256) {
186+
bufferedImageWidth = 256;
187+
}
188+
189+
double maxValue = getMaxValue();
190+
191+
BufferedImage bufferedImage = new BufferedImage(bufferedImageWidth, bufferedImageHeight, BufferedImage.TYPE_INT_ARGB);
192+
makeBufferedImageTransparent(bufferedImage);
193+
Graphics2D bufferedGraphics = null;
194+
try
195+
{
196+
bufferedGraphics = bufferedImage.createGraphics();
197+
198+
for (int x = 0; x < NUM_BARS; x++) {
199+
double currentValue = getValue(x);
200+
double percentOfMax = currentValue / maxValue;
201+
double heightPercentOfPanel = percentOfMax * BAR_HEIGHT_PERCENT;
202+
int height = (int) (heightPercentOfPanel * (double) getHeight());
203+
int xBegin = x + (barWidth - 1) * x;
204+
int yBegin = getHeight() - height;
205+
206+
int val = barColours[x] * 2;
207+
if (val > 190) {
208+
bufferedGraphics.setColor(new Color(255 - val, 255, 255 - val));
209+
}
210+
else {
211+
bufferedGraphics.setColor(new Color(255, 255 - val, 255 - val));
212+
}
213+
bufferedGraphics.fillRect(xBegin, yBegin, barWidth, height);
214+
if (barColours[x] > 0) {
215+
barColours[x] -= 5;
216+
}
217+
}
218+
}
219+
finally
220+
{
221+
if(bufferedGraphics != null)
222+
{
223+
bufferedGraphics.dispose();
224+
}
225+
}
226+
227+
panelGraphics.drawImage(bufferedImage, 0, 0, getWidth(), getHeight(), 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), null);
228+
}
229+
}
230+
231+
private void makeBufferedImageTransparent(BufferedImage image)
232+
{
233+
Graphics2D bufferedGraphics = null;
234+
try
235+
{
236+
bufferedGraphics = image.createGraphics();
237+
238+
bufferedGraphics.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR));
239+
bufferedGraphics.fillRect(0, 0, image.getWidth(), image.getHeight());
240+
bufferedGraphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
241+
}
242+
finally
243+
{
244+
if(bufferedGraphics != null)
245+
{
246+
bufferedGraphics.dispose();
247+
}
248+
}
249+
}
250+
251+
@Override
252+
public void setName(String algorithmName) {
253+
this.algorithmName = algorithmName;
254+
}
255+
public void setComplexity(String tandCcomplexity){
256+
this.tandComplexity = tandCcomplexity;
257+
}
258+
259+
public void setAlgorithm(ISortAlgorithm algorithm) {
260+
this.algorithm = algorithm;
261+
algorithmDelay = algorithm.getDelay();
262+
spinner.setValue((int) algorithm.getDelay());
263+
}
264+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package sortvisualiser.algorithms;
2+
3+
import sortvisualiser.SortArray;
4+
5+
/**
6+
* Bubble sort implementation
7+
*
8+
* @author mhops
9+
*/
10+
public class BubbleSort implements ISortAlgorithm {
11+
12+
private long stepDelay = 2;
13+
/**
14+
* This method implements the bubble sort algorithm, see
15+
* <a href="https://en.wikipedia.org/wiki/Bubble_sort">Bubble_sort</a> to understand more.
16+
* Takes a SortArray object called array and sorts his elements according to the mathematical theory
17+
* of the order "less than", see <a href="https://en.wikipedia.org/wiki/Order_theory">Order_theory</a> to
18+
* understand more.
19+
*
20+
* @param array the array to be sorted
21+
* @see SortArray
22+
*/
23+
@Override
24+
public void runSort(SortArray array) {
25+
int len = array.arraySize();
26+
for (int i = 0; i < len - 1; i++) {
27+
for (int j = 0; j < len - i - 1; j++) {
28+
if (array.getValue(j) > array.getValue(j + 1)) {
29+
array.swap(j, j + 1, getDelay(), true);
30+
}
31+
}
32+
}
33+
}
34+
35+
@Override
36+
public String getName() {
37+
return "Bubble Sort";
38+
}
39+
public String getName1() {
40+
return "Time: (nlogn)\n Space: O(n)";
41+
}
42+
43+
@Override
44+
public long getDelay() {
45+
return stepDelay;
46+
}
47+
48+
@Override
49+
public void setDelay(long delay) {
50+
this.stepDelay = delay;
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package sortvisualiser.algorithms;
2+
import sortvisualiser.SortArray;
3+
4+
/**
5+
* Base interface for the sort algorithms
6+
*
7+
* @author Matt Hopson
8+
*/
9+
public interface ISortAlgorithm {
10+
String getName();
11+
12+
long getDelay();
13+
14+
void setDelay(long delay);
15+
16+
void runSort(SortArray array);
17+
18+
String getName1();
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package sortvisualiser.algorithms;
2+
3+
import sortvisualiser.SortArray;
4+
5+
/**
6+
* Insertion sort implementation
7+
*
8+
* @author Matthew Hopson
9+
*/
10+
public class InsertionSort implements ISortAlgorithm {
11+
12+
private long stepDelay = 1;
13+
/**
14+
* This method implements the insertion sort algorithm, see
15+
* <a href="https://en.wikipedia.org/wiki/Insertion_sort">Insertion_sort</a> to understand more.
16+
* Takes a SortArray object called array and sorts his elements according to the mathematical theory
17+
* of the order "less than", see <a href="https://en.wikipedia.org/wiki/Order_theory">Order_theory</a> to
18+
* understand more.
19+
*
20+
* @param array the array to be sorted
21+
* @see SortArray
22+
*/
23+
@Override
24+
public void runSort(SortArray array) {
25+
for (int i = 0; i < array.arraySize(); i++) {
26+
int key = array.getValue(i);
27+
int j = i - 1;
28+
while (j >= 0 && array.getValue(j) > key) {
29+
array.updateSingle(j + 1, array.getValue(j), 5, true);
30+
j--;
31+
}
32+
array.updateSingle(j + 1, key, getDelay(), true);
33+
}
34+
}
35+
36+
@Override
37+
public String getName() {
38+
return "Insertion Sort";
39+
}
40+
public String getName1() {
41+
return "Time: (nlogn)\n Space: O(n)";
42+
}
43+
44+
@Override
45+
public long getDelay() {
46+
return stepDelay;
47+
}
48+
49+
@Override
50+
public void setDelay(long delay) {
51+
this.stepDelay = delay;
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package sortvisualiser.algorithms;
2+
3+
import sortvisualiser.SortArray;
4+
5+
/**
6+
* Merge sort implementation
7+
*
8+
* @author Matthew Hopson
9+
*/
10+
public class MergeSort implements ISortAlgorithm {
11+
12+
private long stepDelay = 20;
13+
/**
14+
* Returns a subsequence of the array take from input. The original array is cut starting
15+
* from begin position indicated by the homonymous parameter up to (begin + size) position.
16+
*
17+
* @param array this is the array tu cut
18+
* @param begin it represents the start position of the subsequence
19+
* @param size is the length of the subsequence
20+
* @return the subsequence of the array
21+
* @see SortArray
22+
*/
23+
private int[] getSubArray(SortArray array, int begin, int size) {
24+
int arr[] = new int[size];
25+
for (int i = 0; i < size; i++) {
26+
arr[i] = array.getValue(begin + i);
27+
}
28+
return arr;
29+
}
30+
31+
/**
32+
* This is the core of the algorithm merge sort,
33+
* take the array from input and do the cut and merge things.
34+
*
35+
* @param array this is the array to cut and merge
36+
* @param left the left index of the array
37+
* @param middle the middle index of the array
38+
* @param right the right index of the array
39+
* @see SortArray
40+
*/
41+
private void merge(SortArray array, int left, int middle, int right) {
42+
int leftSize = middle - left + 1;
43+
int rightSize = right - middle;
44+
45+
int leftArray[] = getSubArray(array, left, leftSize);
46+
int rightArray[] = getSubArray(array, middle + 1, rightSize);
47+
48+
int i = 0, j = 0, k = left;
49+
while (i < leftSize && j < rightSize) {
50+
if (leftArray[i] <= rightArray[j]) {
51+
array.updateSingle(k, leftArray[i], getDelay(), true);
52+
i++;
53+
} else {
54+
array.updateSingle(k, rightArray[j], getDelay(), true);
55+
j++;
56+
}
57+
k++;
58+
}
59+
60+
while (i < leftSize) {
61+
array.updateSingle(k, leftArray[i], getDelay(), true);
62+
i++;
63+
k++;
64+
}
65+
66+
while (j < rightSize) {
67+
array.updateSingle(k, rightArray[j], getDelay(), true);
68+
j++;
69+
k++;
70+
}
71+
}
72+
73+
/**
74+
* Merge sort is a "divide and conquer" algorithm, it works by splitting the array into tiny sections
75+
* sorting them indivually, and then finally merges it back together, see
76+
* <a href="https://en.wikipedia.org/wiki/Merge_sort">Merge_sort</a> to understand more.
77+
* The method takes a SortArray object called array and sorts his elements according to the mathematical theory
78+
* of the order "less than", see <a href="https://en.wikipedia.org/wiki/Order_theory">Order_theory</a> to
79+
* understand more.
80+
* Recursion was adopted for simplicity
81+
*
82+
* @param array the array to be sorted
83+
* @param left the left index of the array
84+
* @param right the right index of the array
85+
* @see SortArray
86+
*/
87+
private void mergeSort(SortArray array, int left, int right) {
88+
if (left < right) {
89+
int middleIndex = (left + right) / 2;
90+
91+
mergeSort(array, left, middleIndex);
92+
mergeSort(array, middleIndex + 1, right);
93+
merge(array, left, middleIndex, right);
94+
}
95+
}
96+
97+
/**
98+
* This is the method that call the first instance of mergeSort.
99+
* Merge sort is a "divide and conquer" algorithm, it works by splitting the array into tiny sections
100+
* sorting them indivually, and then finally merges it back together, see
101+
* <a href="https://en.wikipedia.org/wiki/Merge_sort">Merge_sort</a> to understand more.
102+
* The method takes a SortArray object called array and sorts his elements according to the mathematical theory
103+
* of the order "less than", see <a href="https://en.wikipedia.org/wiki/Order_theory">Order_theory</a> to
104+
* understand more.
105+
*
106+
* @param array the array to be sorted
107+
* @see SortArray
108+
*/
109+
@Override
110+
public void runSort(SortArray array) {
111+
int left = 0;
112+
int right = array.arraySize() - 1;
113+
mergeSort(array, left, right);
114+
}
115+
116+
@Override
117+
public String getName() {
118+
return "Merge Sort";
119+
}
120+
public String getName1() {
121+
return "Time: (nlogn)\n Space: O(n)";
122+
}
123+
124+
@Override
125+
public long getDelay() {
126+
return stepDelay;
127+
}
128+
129+
@Override
130+
public void setDelay(long delay) {
131+
this.stepDelay = delay;
132+
}
133+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package sortvisualiser.algorithms;
2+
3+
import sortvisualiser.SortArray;
4+
5+
public class QuickSort implements ISortAlgorithm {
6+
7+
private long stepDelay = 30;
8+
private int findPivotPoint(SortArray array, int lowIndex, int highIndex) {
9+
int pivotValue = array.getValue(highIndex);
10+
int i = lowIndex - 1;
11+
for (int j = lowIndex; j <= highIndex - 1; j++) {
12+
if (array.getValue(j) <= pivotValue) {
13+
i++;
14+
array.swap(i, j, getDelay(), true);
15+
}
16+
}
17+
array.swap(i + 1, highIndex, getDelay(), true);
18+
return i + 1;
19+
}
20+
21+
private void quickSort(SortArray array, int lowIndex, int highIndex) {
22+
if (lowIndex < highIndex) {
23+
int pivotPoint = findPivotPoint(array, lowIndex, highIndex);
24+
quickSort(array, lowIndex, pivotPoint - 1);
25+
quickSort(array, pivotPoint + 1, highIndex);
26+
}
27+
}
28+
29+
@Override
30+
public void runSort(SortArray array) {
31+
quickSort(array, 0, array.arraySize() - 1);
32+
}
33+
34+
@Override
35+
public String getName() {
36+
return "Quick Sort";
37+
}
38+
public String getName1() {
39+
return "Time: (nlogn)\n Space: O(n)";
40+
}
41+
42+
@Override
43+
public long getDelay() {
44+
return stepDelay;
45+
}
46+
47+
@Override
48+
public void setDelay(long delay) {
49+
this.stepDelay = delay;
50+
}
51+
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package sortvisualiser.algorithms;
2+
import java.util.Arrays;
3+
import sortvisualiser.SortArray;
4+
5+
/**
6+
* Radix sort implementation
7+
*
8+
* @author Randy Bushman
9+
*/
10+
public class RadixSort implements ISortAlgorithm {
11+
12+
private long stepDelay = 5;
13+
private int radix;
14+
private int[] countingArr;
15+
16+
/**
17+
* @param radix The number system that you wish to work in. Must be greater than zero.
18+
*/
19+
public RadixSort(int radix)
20+
{
21+
this.radix = radix;
22+
countingArr = new int[radix];
23+
}
24+
25+
/**
26+
* Sets Radix to 10 by default.
27+
*/
28+
public RadixSort()
29+
{
30+
this(10);
31+
}
32+
33+
/**
34+
* This is the method that call the first instance of Radix Sort.
35+
* Radix Sort is a non comparison based algorithm that uses counting sort as a subroutine.
36+
* It works by sorting by the least significant digit from smallest to largest. It then
37+
* sorts the next least significant digit and so on. We are not limited to the decimal number
38+
* system however. We can sort in Hex, Binary, etc; hence the name Radix Sort.
39+
*
40+
* @param array the array to be sorted
41+
* @see SortArray
42+
*/
43+
@Override
44+
public void runSort(SortArray array)
45+
{
46+
int largest = array.getMaxValue();
47+
int[] result = new int[array.arraySize()];
48+
49+
for(int exp = 1; largest/exp > 0; exp *= radix) //in real life if Radix was 2, then we would bit shift.
50+
{
51+
countingArr = countingSort(array, exp);
52+
53+
for(int i = 0; i < result.length; ++i)
54+
array.updateSingle(i, result[i] = array.getValue(i), getDelay(), false);
55+
56+
for(int i = 1; i < radix; ++i)
57+
countingArr[i] += countingArr[i-1];
58+
59+
for(int i = array.arraySize() - 1; i > -1 ; --i)
60+
array.updateSingle(--countingArr[(result[i]/exp)%radix], result[i], getDelay(), true);
61+
}
62+
}
63+
64+
/**
65+
* Performs a Counting Sort subroutine
66+
* @param arr The array being sorted
67+
* @param exp The current exponent
68+
* @return A counting array that gives new indices to all values
69+
*/
70+
private int[] countingSort(SortArray arr, int exp)
71+
{
72+
Arrays.fill(countingArr, 0);
73+
for(int i = 0; i < arr.arraySize(); ++i)
74+
countingArr[(arr.getValue(i)/exp)%radix]++;
75+
return countingArr;
76+
}
77+
78+
@Override
79+
public String getName() {
80+
return "Radix Sort (Base " + radix + ")";
81+
}
82+
public String getName1() {
83+
return "Time: (nlogn)\n Space: O(n)";
84+
}
85+
86+
@Override
87+
public long getDelay() {
88+
return stepDelay;
89+
}
90+
91+
@Override
92+
public void setDelay(long delay) {
93+
this.stepDelay = delay;
94+
}
95+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package sortvisualiser.algorithms;
2+
3+
import sortvisualiser.SortArray;
4+
5+
/**
6+
* Selection sort implementation
7+
*
8+
* @author Matt Hopson
9+
*/
10+
public class SelectionSort implements ISortAlgorithm {
11+
12+
private long stepDelay = 120;
13+
/**
14+
* This method implements the Selection sort algorithm, see
15+
* <a href="https://en.wikipedia.org/wiki/Selection_sort">Selection_sort</a> to understand more.
16+
* Takes a SortArray object called array and sorts his elements according to the mathematical theory
17+
* of the order "less than", see <a href="https://en.wikipedia.org/wiki/Order_theory">Order_theory</a> to
18+
* understand more.
19+
*
20+
* @param array the array to be sorted
21+
* @see SortArray
22+
*/
23+
@Override
24+
public void runSort(SortArray array) {
25+
int len = array.arraySize();
26+
for (int i = 0; i < len - 1; i++) {
27+
int minIndex = i;
28+
for (int j = i + 1; j < len; j++) {
29+
if (array.getValue(j) < array.getValue(minIndex)) {
30+
minIndex = j;
31+
}
32+
}
33+
array.swap(i, minIndex, getDelay(), true);
34+
}
35+
}
36+
37+
@Override
38+
public String getName() {
39+
return "Selection Sort";
40+
}
41+
public String getName1() {
42+
return "Time: (nlogn)\n Space: O(n)";
43+
}
44+
45+
@Override
46+
public long getDelay() {
47+
return stepDelay;
48+
}
49+
50+
@Override
51+
public void setDelay(long delay) {
52+
this.stepDelay = delay;
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package sortvisualiser.screens;
2+
3+
import java.awt.CheckboxGroup;
4+
import java.awt.Color;
5+
import java.awt.Component;
6+
import java.awt.Dimension;
7+
import java.awt.event.ActionEvent;
8+
import java.awt.image.BufferedImage;
9+
import java.io.File;
10+
import java.io.IOException;
11+
import java.util.ArrayList;
12+
13+
import javax.imageio.ImageIO;
14+
import javax.swing.*;
15+
16+
import sortvisualiser.MainApp;
17+
import sortvisualiser.algorithms.*;
18+
19+
20+
public final class MainMenuScreen extends Screen {
21+
private static final Color BACKGROUND_COLOUR = Color.BLUE;
22+
private final ArrayList<AlgorithmCheckBox> checkBoxes;
23+
24+
public MainMenuScreen(MainApp app) {
25+
super(app);
26+
checkBoxes = new ArrayList<>();
27+
setUpGUI();
28+
}
29+
30+
private void addCheckBox(ISortAlgorithm algorithm, JPanel panel) {
31+
JRadioButton box = new JRadioButton("", true);
32+
box.setAlignmentX(Component.LEFT_ALIGNMENT);
33+
box.setBackground(BACKGROUND_COLOUR);
34+
box.setForeground(Color.WHITE);
35+
checkBoxes.add(new AlgorithmCheckBox(algorithm, box));
36+
panel.add(box);
37+
}
38+
39+
private void initContainer(JPanel p) {
40+
p.setLayout(new BoxLayout(p, BoxLayout.PAGE_AXIS));
41+
p.setBackground(BACKGROUND_COLOUR);
42+
//p.setBorder(BorderFactory.createLineBorder(Color.WHITE));
43+
}
44+
45+
public void setUpGUI() {
46+
JPanel sortAlgorithmContainer = new JPanel();
47+
JPanel optionsContainer = new JPanel();
48+
JPanel outerContainer = new JPanel();
49+
initContainer(this);
50+
initContainer(optionsContainer);
51+
initContainer(sortAlgorithmContainer);
52+
53+
outerContainer.setBackground(BACKGROUND_COLOUR);
54+
outerContainer.setLayout(new BoxLayout(outerContainer, BoxLayout.LINE_AXIS));
55+
56+
try {
57+
ClassLoader loader = getClass().getClassLoader();
58+
BufferedImage image = ImageIO.read(new File(loader.getResource("logo.png").getFile()));
59+
JLabel label = new JLabel(new ImageIcon(image));
60+
label.setAlignmentX(Component.LEFT_ALIGNMENT);
61+
add(label);
62+
} catch (IOException e) {
63+
System.out.println("Unable to load logo");
64+
}
65+
66+
sortAlgorithmContainer.setAlignmentX(Component.LEFT_ALIGNMENT);
67+
addCheckBox(new BubbleSort(), sortAlgorithmContainer);
68+
addCheckBox(new SelectionSort(), sortAlgorithmContainer);
69+
addCheckBox(new QuickSort(), sortAlgorithmContainer);
70+
addCheckBox(new MergeSort(), sortAlgorithmContainer);
71+
addCheckBox(new InsertionSort(), sortAlgorithmContainer);
72+
addCheckBox(new RadixSort(), sortAlgorithmContainer);
73+
74+
// JCheckBox soundCheckBox = new JCheckBox("Play Sounds");
75+
// soundCheckBox.setAlignmentX(Component.LEFT_ALIGNMENT);
76+
// soundCheckBox.setBackground(BACKGROUND_COLOUR);
77+
// soundCheckBox.setForeground(Color.WHITE);
78+
79+
// optionsContainer.add(soundCheckBox);
80+
81+
JButton startButton = new JButton("Start");
82+
startButton.addActionListener((ActionEvent e) -> {
83+
ArrayList<ISortAlgorithm> algorithms = new ArrayList<>();
84+
for (AlgorithmCheckBox cb : checkBoxes) {
85+
if (cb.isSelected()) {
86+
algorithms.add(cb.getAlgorithm());
87+
}
88+
}
89+
app.pushScreen(
90+
new SortingVisualiserScreen(
91+
algorithms,
92+
// soundCheckBox.isSelected(),
93+
app
94+
));
95+
});
96+
startButton.setAlignmentX(Component.LEFT_ALIGNMENT);
97+
98+
outerContainer.add(optionsContainer);
99+
outerContainer.add(Box.createRigidArea(new Dimension(5,0)));
100+
outerContainer.add(sortAlgorithmContainer);
101+
102+
int gap = 15;
103+
add(Box.createRigidArea(new Dimension(0, gap)));
104+
add(outerContainer);
105+
add(Box.createRigidArea(new Dimension(0, gap)));
106+
add(startButton);
107+
}
108+
109+
@Override
110+
public void onOpen() {
111+
checkBoxes.forEach((box) -> {
112+
box.unselect();
113+
114+
});
115+
116+
}
117+
118+
private class AlgorithmCheckBox {
119+
private final ISortAlgorithm algorithm;
120+
private final JRadioButton box;
121+
122+
public AlgorithmCheckBox(ISortAlgorithm algorithm, JRadioButton box) {
123+
this.algorithm = algorithm;
124+
this.box = box;
125+
this.box.setText(algorithm.getName());
126+
}
127+
128+
public void unselect() {
129+
box.setSelected(false);
130+
}
131+
132+
133+
public boolean isSelected() {
134+
return box.isSelected();
135+
}
136+
137+
public ISortAlgorithm getAlgorithm() {
138+
return algorithm;
139+
}
140+
}
141+
142+
}
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package sortvisualiser.screens;
2+
3+
import static sortvisualiser.MainApp.WIN_HEIGHT;
4+
import static sortvisualiser.MainApp.WIN_WIDTH;
5+
6+
import java.awt.Dimension;
7+
8+
import javax.swing.JPanel;
9+
10+
import sortvisualiser.MainApp;
11+
12+
public abstract class Screen extends JPanel {
13+
protected MainApp app;
14+
15+
public Screen(MainApp app) {
16+
this.app = app;
17+
}
18+
19+
@Override
20+
public Dimension getPreferredSize() {
21+
return new Dimension(WIN_WIDTH, WIN_HEIGHT);
22+
}
23+
24+
public abstract void onOpen();
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package sortvisualiser.screens;
2+
3+
import java.awt.BorderLayout;
4+
import java.util.ArrayList;
5+
import javax.swing.SwingWorker;
6+
import sortvisualiser.MainApp;
7+
import sortvisualiser.SortArray;
8+
import sortvisualiser.algorithms.ISortAlgorithm;
9+
10+
/**
11+
* The main class for the sort visualiser GUI
12+
*
13+
* @author Matt Hopson
14+
*/
15+
public final class SortingVisualiserScreen extends Screen {
16+
private final SortArray sortArray;
17+
private final ArrayList<ISortAlgorithm> sortQueue;
18+
19+
/**
20+
* Creates the GUI
21+
* @param algorithms List of algorithms to run for visualisation
22+
* @param app The main application
23+
*/
24+
public SortingVisualiserScreen(ArrayList<ISortAlgorithm> algorithms, MainApp app) {
25+
super(app);
26+
setLayout(new BorderLayout());
27+
sortArray = new SortArray();
28+
add(sortArray, BorderLayout.CENTER);
29+
sortQueue = algorithms;
30+
}
31+
32+
private void longSleep() {
33+
try {
34+
Thread.sleep(1000);
35+
} catch (InterruptedException ex) {
36+
ex.printStackTrace();
37+
}
38+
}
39+
40+
private void shuffleAndWait() {
41+
sortArray.shuffle();
42+
sortArray.resetColours();
43+
longSleep();
44+
}
45+
46+
public void onOpen() {
47+
SwingWorker<Void, Void> swingWorker = new SwingWorker<>() {
48+
@Override
49+
protected Void doInBackground() {
50+
try {
51+
Thread.sleep(250);
52+
} catch (InterruptedException ex) {
53+
ex.printStackTrace();
54+
}
55+
for (ISortAlgorithm algorithm : sortQueue) {
56+
shuffleAndWait();
57+
58+
sortArray.setName(algorithm.getName());
59+
sortArray.setComplexity(algorithm.getName1());
60+
sortArray.setAlgorithm(algorithm);
61+
62+
algorithm.runSort(sortArray);
63+
sortArray.resetColours();
64+
sortArray.highlightArray();
65+
sortArray.resetColours();
66+
longSleep();
67+
}
68+
return null;
69+
}
70+
71+
@Override
72+
public void done() {
73+
app.popScreen();
74+
}
75+
};
76+
77+
swingWorker.execute();
78+
}
79+
}

0 commit comments

Comments
 (0)
Please sign in to comment.