Skip to content

Commit 3e9ea98

Browse files
Entire project
1 parent a296780 commit 3e9ea98

File tree

6 files changed

+236
-15
lines changed

6 files changed

+236
-15
lines changed

.prettierrc.json

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"printWidth": 80,
3+
"tabWidth": 2,
4+
"useTabs": false,
5+
"semi": true,
6+
"singleQuote": true,
7+
"jsxSingleQuote": false,
8+
"trailingComma": "all",
9+
"bracketSpacing": false,
10+
"jsxBracketSameLine": true,
11+
"arrowParens": "avoid"
12+
}

.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"editor.formatOnSave": true
3+
}

src/App.js

+2-15
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,11 @@
11
import React from 'react';
2-
import logo from './logo.svg';
2+
import SortingVisualizer from './SortingVisualizer/SortingVisualizer';
33
import './App.css';
44

55
function App() {
66
return (
77
<div className="App">
8-
<header className="App-header">
9-
<img src={logo} className="App-logo" alt="logo" />
10-
<p>
11-
Edit <code>src/App.js</code> and save to reload.
12-
</p>
13-
<a
14-
className="App-link"
15-
href="https://reactjs.org"
16-
target="_blank"
17-
rel="noopener noreferrer"
18-
>
19-
Learn React
20-
</a>
21-
</header>
8+
<SortingVisualizer></SortingVisualizer>
229
</div>
2310
);
2411
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.array-container {
2+
position: absolute;
3+
left: 100px;
4+
/* top: 100px; */
5+
}
6+
7+
.array-bar {
8+
width: 2px;
9+
display: inline-block;
10+
margin: 0 1px;
11+
}
+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import React from 'react';
2+
import {getMergeSortAnimations} from '../sortingAlgorithms/sortingAlgorithms.js';
3+
import './SortingVisualizer.css';
4+
5+
// Change this value for the speed of the animations.
6+
const ANIMATION_SPEED_MS = 1;
7+
8+
// Change this value for the number of bars (value) in the array.
9+
const NUMBER_OF_ARRAY_BARS = 310;
10+
11+
// This is the main color of the array bars.
12+
const PRIMARY_COLOR = 'turquoise';
13+
14+
// This is the color of array bars that are being compared throughout the animations.
15+
const SECONDARY_COLOR = 'red';
16+
17+
export default class SortingVisualizer extends React.Component {
18+
constructor(props) {
19+
super(props);
20+
21+
this.state = {
22+
array: [],
23+
};
24+
}
25+
26+
componentDidMount() {
27+
this.resetArray();
28+
}
29+
30+
resetArray() {
31+
const array = [];
32+
for (let i = 0; i < NUMBER_OF_ARRAY_BARS; i++) {
33+
array.push(randomIntFromInterval(5, 730));
34+
}
35+
this.setState({array});
36+
}
37+
38+
mergeSort() {
39+
const animations = getMergeSortAnimations(this.state.array);
40+
for (let i = 0; i < animations.length; i++) {
41+
const arrayBars = document.getElementsByClassName('array-bar');
42+
const isColorChange = i % 3 !== 2;
43+
if (isColorChange) {
44+
const [barOneIdx, barTwoIdx] = animations[i];
45+
const barOneStyle = arrayBars[barOneIdx].style;
46+
const barTwoStyle = arrayBars[barTwoIdx].style;
47+
const color = i % 3 === 0 ? SECONDARY_COLOR : PRIMARY_COLOR;
48+
setTimeout(() => {
49+
barOneStyle.backgroundColor = color;
50+
barTwoStyle.backgroundColor = color;
51+
}, i * ANIMATION_SPEED_MS);
52+
} else {
53+
setTimeout(() => {
54+
const [barOneIdx, newHeight] = animations[i];
55+
const barOneStyle = arrayBars[barOneIdx].style;
56+
barOneStyle.height = `${newHeight}px`;
57+
}, i * ANIMATION_SPEED_MS);
58+
}
59+
}
60+
}
61+
62+
quickSort() {
63+
// We leave it as an exercise to the viewer of this code to implement this method.
64+
}
65+
66+
heapSort() {
67+
// We leave it as an exercise to the viewer of this code to implement this method.
68+
}
69+
70+
bubbleSort() {
71+
// We leave it as an exercise to the viewer of this code to implement this method.
72+
}
73+
74+
// NOTE: This method will only work if your sorting algorithms actually return
75+
// the sorted arrays; if they return the animations (as they currently do), then
76+
// this method will be broken.
77+
testSortingAlgorithms() {
78+
for (let i = 0; i < 100; i++) {
79+
const array = [];
80+
const length = randomIntFromInterval(1, 1000);
81+
for (let i = 0; i < length; i++) {
82+
array.push(randomIntFromInterval(-1000, 1000));
83+
}
84+
const javaScriptSortedArray = array.slice().sort((a, b) => a - b);
85+
const mergeSortedArray = getMergeSortAnimations(array.slice());
86+
console.log(arraysAreEqual(javaScriptSortedArray, mergeSortedArray));
87+
}
88+
}
89+
90+
render() {
91+
const {array} = this.state;
92+
93+
return (
94+
<div className="array-container">
95+
{array.map((value, idx) => (
96+
<div
97+
className="array-bar"
98+
key={idx}
99+
style={{
100+
backgroundColor: PRIMARY_COLOR,
101+
height: `${value}px`,
102+
}}></div>
103+
))}
104+
<button onClick={() => this.resetArray()}>Generate New Array</button>
105+
<button onClick={() => this.mergeSort()}>Merge Sort</button>
106+
<button onClick={() => this.quickSort()}>Quick Sort</button>
107+
<button onClick={() => this.heapSort()}>Heap Sort</button>
108+
<button onClick={() => this.bubbleSort()}>Bubble Sort</button>
109+
<button onClick={() => this.testSortingAlgorithms()}>
110+
Test Sorting Algorithms (BROKEN)
111+
</button>
112+
</div>
113+
);
114+
}
115+
}
116+
117+
// From https://stackoverflow.com/questions/4959975/generate-random-number-between-two-numbers-in-javascript
118+
function randomIntFromInterval(min, max) {
119+
// min and max included
120+
return Math.floor(Math.random() * (max - min + 1) + min);
121+
}
122+
123+
function arraysAreEqual(arrayOne, arrayTwo) {
124+
if (arrayOne.length !== arrayTwo.length) return false;
125+
for (let i = 0; i < arrayOne.length; i++) {
126+
if (arrayOne[i] !== arrayTwo[i]) {
127+
return false;
128+
}
129+
}
130+
return true;
131+
}
+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
export function getMergeSortAnimations(array) {
2+
const animations = [];
3+
if (array.length <= 1) return array;
4+
const auxiliaryArray = array.slice();
5+
mergeSortHelper(array, 0, array.length - 1, auxiliaryArray, animations);
6+
return animations;
7+
}
8+
9+
function mergeSortHelper(
10+
mainArray,
11+
startIdx,
12+
endIdx,
13+
auxiliaryArray,
14+
animations,
15+
) {
16+
if (startIdx === endIdx) return;
17+
const middleIdx = Math.floor((startIdx + endIdx) / 2);
18+
mergeSortHelper(auxiliaryArray, startIdx, middleIdx, mainArray, animations);
19+
mergeSortHelper(auxiliaryArray, middleIdx + 1, endIdx, mainArray, animations);
20+
doMerge(mainArray, startIdx, middleIdx, endIdx, auxiliaryArray, animations);
21+
}
22+
23+
function doMerge(
24+
mainArray,
25+
startIdx,
26+
middleIdx,
27+
endIdx,
28+
auxiliaryArray,
29+
animations,
30+
) {
31+
let k = startIdx;
32+
let i = startIdx;
33+
let j = middleIdx + 1;
34+
while (i <= middleIdx && j <= endIdx) {
35+
// These are the values that we're comparing; we push them once
36+
// to change their color.
37+
animations.push([i, j]);
38+
// These are the values that we're comparing; we push them a second
39+
// time to revert their color.
40+
animations.push([i, j]);
41+
if (auxiliaryArray[i] <= auxiliaryArray[j]) {
42+
// We overwrite the value at index k in the original array with the
43+
// value at index i in the auxiliary array.
44+
animations.push([k, auxiliaryArray[i]]);
45+
mainArray[k++] = auxiliaryArray[i++];
46+
} else {
47+
// We overwrite the value at index k in the original array with the
48+
// value at index j in the auxiliary array.
49+
animations.push([k, auxiliaryArray[j]]);
50+
mainArray[k++] = auxiliaryArray[j++];
51+
}
52+
}
53+
while (i <= middleIdx) {
54+
// These are the values that we're comparing; we push them once
55+
// to change their color.
56+
animations.push([i, i]);
57+
// These are the values that we're comparing; we push them a second
58+
// time to revert their color.
59+
animations.push([i, i]);
60+
// We overwrite the value at index k in the original array with the
61+
// value at index i in the auxiliary array.
62+
animations.push([k, auxiliaryArray[i]]);
63+
mainArray[k++] = auxiliaryArray[i++];
64+
}
65+
while (j <= endIdx) {
66+
// These are the values that we're comparing; we push them once
67+
// to change their color.
68+
animations.push([j, j]);
69+
// These are the values that we're comparing; we push them a second
70+
// time to revert their color.
71+
animations.push([j, j]);
72+
// We overwrite the value at index k in the original array with the
73+
// value at index j in the auxiliary array.
74+
animations.push([k, auxiliaryArray[j]]);
75+
mainArray[k++] = auxiliaryArray[j++];
76+
}
77+
}

0 commit comments

Comments
 (0)