From 10e3a3b1d45b9f4a8ee54d38a90e9a59322f942d Mon Sep 17 00:00:00 2001 From: Daniel <you@example.com> Date: Thu, 19 Sep 2024 19:29:45 +0200 Subject: [PATCH] Added option to pause sorting --- src/BubbleSort.jsx | 30 +++++++++++++++++++----------- src/MergeSort.js | 31 +++++++++++++++++++++++-------- src/SortingVisualizer.jsx | 24 +++++++++++++++++++----- 3 files changed, 61 insertions(+), 24 deletions(-) diff --git a/src/BubbleSort.jsx b/src/BubbleSort.jsx index 03b4c9d..a00b077 100644 --- a/src/BubbleSort.jsx +++ b/src/BubbleSort.jsx @@ -1,23 +1,31 @@ -async function BubbleSort(EingangsArray, updateBars, setColor, sortSpeed){ +let abortFlag = {isAborted: false}; + +export default async function BubbleSort(EingangsArray, updateBars, setColor, sortSpeed) { const len = EingangsArray.length; - for(let i = 0; i< len -1; ++i){ - for(let k=0; k< len -1-i; k++){ + for (let i = 0; i < len - 1; ++i) { + if (abortFlag.isAborted) return; + + for (let k = 0; k < len - 1 - i; k++) { + if (abortFlag.isAborted) return; let tmp; - if (k == len -2-i){ - setColor([(len-1-i)]); + if (k == len - 2 - i) { + setColor([len - 1 - i]); } - if(EingangsArray[k] > EingangsArray[k+1]){ + if (EingangsArray[k] > EingangsArray[k + 1]) { tmp = EingangsArray[k]; - EingangsArray[k] = EingangsArray[k+1]; - EingangsArray[k+1] = tmp; + EingangsArray[k] = EingangsArray[k + 1]; + EingangsArray[k + 1] = tmp; } updateBars([...EingangsArray]); - await new Promise(resolve => setTimeout(resolve, sortSpeed)); // Pause für Animation + await new Promise(resolve => setTimeout(resolve, sortSpeed)); } } - setColor([(len-len)]); + setColor([len - len]); console.log(EingangsArray); return EingangsArray; } -export default BubbleSort; \ No newline at end of file + +export function abortBubbleSort() { + abortFlag.isAborted = true; +} diff --git a/src/MergeSort.js b/src/MergeSort.js index 2c935a1..4e26060 100644 --- a/src/MergeSort.js +++ b/src/MergeSort.js @@ -1,25 +1,28 @@ -async function MergeSort(EingangsArray, startIdx, endIdx, arrayCopy, updateBars, setColor, sortSpeed) { +let abortFlag = {isAborted: false}; + +async function MergeSort(EingangsArray, startIdx, endIdx, arrayCopy, updateBars, setColor, sortSpeed, abortFlag) { + if (abortFlag.isAborted) return; 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); + await MergeSort(EingangsArray, startIdx, cuttingEdge, arrayCopy, updateBars, setColor, sortSpeed, abortFlag); + await MergeSort(EingangsArray, cuttingEdge + 1, endIdx, arrayCopy, updateBars, setColor, sortSpeed, abortFlag); - // Merge halves back togeteher - await merge(EingangsArray, startIdx, cuttingEdge, endIdx, arrayCopy, updateBars, setColor, sortSpeed); + // Merge halves back together + await merge(EingangsArray, startIdx, cuttingEdge, endIdx, arrayCopy, updateBars, setColor, sortSpeed, abortFlag); } -async function merge(EingangsArray, startIdx, middleIdx, endIdx, arrayCopy, updateBars, setColor, sortSpeed) { +async function merge(EingangsArray, startIdx, middleIdx, endIdx, arrayCopy, updateBars, setColor, sortSpeed, abortFlag) { + if (abortFlag.isAborted) return; 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; @@ -53,6 +56,12 @@ async function merge(EingangsArray, startIdx, middleIdx, endIdx, arrayCopy, upda 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 = ''; + if (abortFlag.isAborted) { + bars.forEach(bar => { + bar.style.backgroundColor = ''; + }); + return; + } k++; } @@ -73,6 +82,7 @@ async function merge(EingangsArray, startIdx, middleIdx, endIdx, arrayCopy, upda arrayCopy[k] = EingangsArray[i]; await updateArrayState(EingangsArray, arrayCopy, startIdx, endIdx, updateBars, sortSpeed); if (isValidIndex(i)) bars[i].style.backgroundColor = ''; + if (abortFlag.isAborted) return; i++; k++; @@ -94,6 +104,7 @@ async function merge(EingangsArray, startIdx, middleIdx, endIdx, arrayCopy, upda arrayCopy[k] = EingangsArray[j]; await updateArrayState(EingangsArray, arrayCopy, startIdx, endIdx, updateBars, sortSpeed); if (isValidIndex(j)) bars[j].style.backgroundColor = ''; + if (abortFlag.isAborted) return; j++; k++; @@ -116,7 +127,11 @@ async function updateArrayState(EingangsArray, arrayCopy, startIdx, endIdx, upda } export default async function startMergeSort(EingangsArray, updateBars, setFinish, sortSpeed) { + abortFlag.isAborted = false; const arrayCopy = [...EingangsArray]; + await MergeSort(EingangsArray, 0, EingangsArray.length - 1, arrayCopy, updateBars, setFinish, sortSpeed, abortFlag); +} - await MergeSort(EingangsArray, 0, EingangsArray.length - 1, arrayCopy, updateBars, setFinish, sortSpeed); +export function abortMergeSort() { + abortFlag.isAborted = true; } diff --git a/src/SortingVisualizer.jsx b/src/SortingVisualizer.jsx index 066cd9b..af42fba 100644 --- a/src/SortingVisualizer.jsx +++ b/src/SortingVisualizer.jsx @@ -1,7 +1,7 @@ import {useState, useEffect} from 'react'; import './SortingVisualizer.css' -import BubbleSort from "./BubbleSort"; -import startMergeSort from "./MergeSort.js"; +import BubbleSort, {abortBubbleSort} from "./BubbleSort"; +import startMergeSort, {abortMergeSort} 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'; @@ -44,7 +44,7 @@ function SortingVisualizer() { } function generateArray(numberBars) { - return Array.from({length: numberBars}, () => getRandomArbitrary(20, 400)); + return Array.from({length: numberBars}, () => getRandomArbitrary(20, 450)); } async function handleSorting() { @@ -88,6 +88,20 @@ function SortingVisualizer() { } } + async function stopSorting() { + switch (Algo) { + case 'BubbleSort': + abortBubbleSort(); + break; + case 'MergeSort': + abortMergeSort(); + break; + } + await new Promise(resolve => setTimeout(resolve, 200)); + document.getElementById('startButton').innerText = 'Reset!'; + setIsSorted(true); + } + useEffect(() => { if (alreadySorted == 0) { setIsSorted(true); @@ -166,9 +180,9 @@ function SortingVisualizer() { </Dropdown.Menu> </Dropdown> - <button id='startButton' className="Button" disabled={sorting} + <button id='startButton' className="Button" style={{background: `${sorting ? 'red' : ''}`}} onClick={() => { - handleButton() + sorting ? stopSorting() : handleButton() }}>{sorting ? 'Sorting...' : 'Sort!'}</button> </div> <div className='DivArray'> -- GitLab