Skip to content
Snippets Groups Projects
Commit 7b3d1958 authored by Daniel Runte's avatar Daniel Runte
Browse files

Merge branch 'feature/MergeSort' into 'main'

implemented MergeSort

See merge request !3
parents 0aedb6dc daf09a14
No related branches found
No related tags found
1 merge request!3implemented MergeSort
Pipeline #224003 passed
......@@ -18,6 +18,7 @@ COPY vite.config.js .
# port 5173
EXPOSE 5173
EXPOSE 9229
#Start
CMD ["npm", "run", "dev", "--", "--host"]
CMD ["npm", "run", "dev", "--", "--host", "$DEBUG_FLAG"]
......@@ -4,13 +4,16 @@ services:
container_name: Sorting-Visualizer
ports:
- 127.0.0.1:5173:5173
- 127.0.0.1:9229:9229
volumes:
- ./src/:/app/sorting-visualizer/src/
- ./package-lock.json:/app/sorting-visualizer/package-lock.json
- ./package.json:/app/sorting-visualizer/package.json
networks:
- my-network
environment:
DEBUG_FLAG: "--inspect=0.0.0.0:9229"
networks:
my-network:
driver: bridge
async function MergeSort(EingangsArray, startIdx, endIdx, arrayCopy, updateBars, setColor, sortSpeed) {
if (startIdx >= endIdx) return;
// Split array
const cuttingEdge = Math.floor((startIdx + endIdx) / 2);
// Recursively sort both halves
await MergeSort(EingangsArray, startIdx, cuttingEdge, arrayCopy, updateBars, setColor, sortSpeed);
await MergeSort(EingangsArray, cuttingEdge + 1, endIdx, arrayCopy, updateBars, setColor, sortSpeed);
// Merge halves back togeteher
await merge(EingangsArray, startIdx, cuttingEdge, endIdx, arrayCopy, updateBars, setColor, sortSpeed);
}
async function merge(EingangsArray, startIdx, middleIdx, endIdx, arrayCopy, updateBars, setColor, sortSpeed) {
let i = startIdx;
let j = middleIdx + 1;
let k = startIdx;
const bars = document.querySelectorAll('.bar'); // get all bars
const sortSpeedSwitch = Number(sortSpeed);
// index exist?
const isValidIndex = (index) => index >= 0 && index < bars.length;
// Merge halves back togeteher
while (i <= middleIdx && j <= endIdx) {
if (isValidIndex(i) && isValidIndex(j)) {
// Change color of compared bars
bars[i].style.backgroundColor = 'red';
bars[j].style.backgroundColor = 'red';
}
switch (sortSpeedSwitch) {
case 0:
break; // No delay
case 40:
await new Promise(resolve => setTimeout(resolve, 90));
break;
case 100:
await new Promise(resolve => setTimeout(resolve, 200));
break;
}
if (EingangsArray[i] <= EingangsArray[j]) {
arrayCopy[k] = EingangsArray[i];
i++;
} else {
arrayCopy[k] = EingangsArray[j];
j++;
}
// Update Array
await updateArrayState(EingangsArray, arrayCopy, startIdx, endIdx, updateBars, sortSpeed);
if (isValidIndex(i - 1)) bars[i - 1].style.backgroundColor = ''; // default colr
if (isValidIndex(j - 1)) bars[j - 1].style.backgroundColor = '';
k++;
}
// Copy from the LEFT half
while (i <= middleIdx) {
switch (sortSpeedSwitch) {
case 0:
break; // No delay
case 40:
await new Promise(resolve => setTimeout(resolve, 90));
break;
case 100:
await new Promise(resolve => setTimeout(resolve, 200));
break;
}
arrayCopy[k] = EingangsArray[i];
await updateArrayState(EingangsArray, arrayCopy, startIdx, endIdx, updateBars, sortSpeed);
if (isValidIndex(i)) bars[i].style.backgroundColor = '';
i++;
k++;
}
// Copy from the RIGHT half
while (j <= endIdx) {
switch (sortSpeedSwitch) {
case 0:
break; // No delay
case 40:
await new Promise(resolve => setTimeout(resolve, 90));
break;
case 100:
await new Promise(resolve => setTimeout(resolve, 200));
break;
}
arrayCopy[k] = EingangsArray[j];
await updateArrayState(EingangsArray, arrayCopy, startIdx, endIdx, updateBars, sortSpeed);
if (isValidIndex(j)) bars[j].style.backgroundColor = '';
j++;
k++;
}
// Copy merged values back
for (let i = startIdx; i <= endIdx; i++) {
EingangsArray[i] = arrayCopy[i];
}
// adding to class 'finished'
if (endIdx - startIdx + 1 === EingangsArray.length) {
setColor(0);
}
}
async function updateArrayState(EingangsArray, arrayCopy, startIdx, endIdx, updateBars, sortSpeed) {
updateBars([...arrayCopy]);
await new Promise(resolve => setTimeout(resolve, sortSpeed));
}
export default async function startMergeSort(EingangsArray, updateBars, setFinish, sortSpeed) {
const arrayCopy = [...EingangsArray];
await MergeSort(EingangsArray, 0, EingangsArray.length - 1, arrayCopy, updateBars, setFinish, sortSpeed);
}
......@@ -15,6 +15,9 @@ body {
height: 100px;
flex: 1 1 20px;
min-width: 2px;
margin: 0px;
transform-origin: bottom;
}
.sorted {
......@@ -75,13 +78,20 @@ button:active {
}
.DivArray {
transform: scaleY(-1);
display: flex;
position: absolute;
position: fixed;
flex-wrap: nowrap;
justify-content: center;
gap: 2px;
width: 90%;
margin-top: 5px;
margin-top: 60px;
align-items: flex-end;
overflow: hidden;
height: 400px;
/
}
#dropdown-menu {
......@@ -91,7 +101,6 @@ button:active {
margin-top: 3px;
}
#dropdown-item {
color: white;
font-size: 16px;
......@@ -115,7 +124,6 @@ button:active {
height: 100%;
display: flex;
place-items: center;
margin-inline: 10px;
justify-content: center;
width: 195px;
transition: none;
......@@ -135,6 +143,17 @@ button:active {
color: white;
}
.Divider {
background: gray;
height: 70%;
margin-left: 8px;
margin-right: 3px;
width: 2px;
}
#dividerLeft {
margin-right: 8px;
}
@keyframes ScaleAnimation {
0% {
......
import {useState, useEffect} from 'react';
import './SortingVisualizer.css'
import BubbleSort from "./BubbleSort";
import startMergeSort from "./MergeSort.js";
import RangeSlider from 'react-bootstrap-range-slider';
import 'react-bootstrap-range-slider/dist/react-bootstrap-range-slider.css';
import {Dropdown} from 'react-bootstrap';
......@@ -13,9 +14,10 @@ function SortingVisualizer() {
const [BarNumber, setBarNumber] = useState(() => monitorSize > 100 ? 100 : monitorSize); // max of 100 bars
const [bars, setbars] = useState(() => generateArray(BarNumber));
const [sorting, setSorting] = useState(false);
const [alreadySorted, setAlreadySorted] = useState();
const [alreadySorted, setColor] = useState();
const [isSorted, setIsSorted] = useState(false);
const [sortSpeed, setSortSpeed] = useState('40');
const [Algo, setAlgo] = useState('BubbleSort');
const SliderWithInputFormControl = () => {
const [sliderValue_intern, setSliderValue_intern] = useState(BarNumber);
......@@ -41,18 +43,22 @@ function SortingVisualizer() {
}
function generateArray(numberBars) {
return Array.from({length: numberBars}, () => getRandomArbitrary(50, 300));
return Array.from({length: numberBars}, () => getRandomArbitrary(20, 400));
}
async function handleSorting() {
if (sorting) return;
setSorting(true);
await BubbleSort(bars, setbars, setAlreadySorted, sortSpeed);
if (Algo == 'BubbleSort') {
await BubbleSort(bars, setbars, setColor, sortSpeed);
} else if (Algo == 'MergeSort') {
await startMergeSort(bars, setbars, setColor, sortSpeed);
}
setSorting(false);
}
function resetBars() {
setAlreadySorted(1000);
setColor(1000);
setbars(generateArray(BarNumber));
let ColoredBars = document.getElementsByClassName('sorted');
document.getElementById('startButton').innerText = 'Sort!';
......@@ -73,7 +79,7 @@ function SortingVisualizer() {
function handleButton() {
if (!sorting && !isSorted) {
setAlreadySorted(1000);
setColor(1000);
handleSorting();
} else if (isSorted) {
resetBars();
......@@ -106,14 +112,15 @@ function SortingVisualizer() {
value={BarNumber} style={{
width: '42px',
fontfamily: 'Arial sans-serif',
fontSize:'16px',
margin: '10px',
fontSize: '16px',
marginLeft: '10px',
marginRight: '5px',
borderRadius: '5px',
border: 'none',
textAlign: 'center'
}}/>
<div style={{background: 'gray', height: '70%', marginLeft: '10px', width: '2px'}}></div>
<Dropdown id="dropdown">
<div id="dividerLeft" className="Divider"></div>
<Dropdown id="dropdown" className="dropdown-wide">
<Dropdown.Toggle
id="dropdown"
disabled={sorting}
......@@ -138,6 +145,26 @@ function SortingVisualizer() {
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<div className="Divider"></div>
<Dropdown id="dropdown">
<Dropdown.Toggle
id="dropdown"
disabled={sorting}
>
Algorithm: {
[Algo]
}
</Dropdown.Toggle>
<Dropdown.Menu id="dropdown-menu">
<Dropdown.Item id="dropdown-item" onClick={() => setAlgo('BubbleSort')}>
BubbleSort
</Dropdown.Item>
<Dropdown.Item id="dropdown-item" onClick={() => setAlgo('MergeSort')}>
MergeSort
</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
<button id='startButton' className="Button" disabled={sorting}
style={{background: `${sorting ? 'red' : ''}`}} onClick={() => {
handleButton()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment