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