Can do merge sort but having problem animating the merge sort visualizer in react

42 views Asked by At

My program is currently sorting the array correctly with merge sort. But the problem is the animation part.

In the code, since i am using setArr() with sorted large block of elements of the original array, the animation is also changing in large block of sorted elements. Therefore, the sorting animations are happening so quickly. Instead, of that, i want the animation to change one element after one element in sorted order.

Thank you in advance.

Here is the my current merge sort code:

export function mergeSort(arr, setArr, styling, setStyling, speed) {
    async function performMerge(start, middle, end) {
        setArr(preArr => {
            let buffer_arr = [...preArr];
            let buffer_style = [...styling];
            let merged = [];

            let left_buffer = buffer_arr.slice(start, middle + 1);
            let right_buffer = buffer_arr.slice(middle + 1, end + 1);

            while (left_buffer.length > 0 && right_buffer.length > 0) {
                if (left_buffer[0] > right_buffer[0]) merged.push(right_buffer.shift());
                else merged.push(left_buffer.shift());
            }
            merged = merged.concat(left_buffer, right_buffer);
            for (let i = start, j = 0; i < end + 1; i++, j++) {
                buffer_style[i] = "green";
                setStyling([...buffer_style]);
                buffer_arr[i] = merged[j];
            }
            return buffer_arr;
        });

        await new Promise((resolve) => {
            setTimeout(() => {
                resolve();
            }, speed);
        });
    }

    async function performSplit(start, end) {
        if (start < end) {
            const middle = Math.floor((start + end) / 2);
    
            await performSplit(start, middle);
            await performSplit(middle + 1, end);

            await performMerge(start, middle, end);   
        }
    }
    performSplit(0, arr.length - 1);
}

I have tried correcting the performMerge function by using setArr() inside the for loop. The animation is work as i expected but the original array is not updated with partially sorted elements anymore by setArr(). Because of that, the array are not correctly sorted anymore.

Here the updated performMerge function that i have tried:

async function performMerge(start, middle, end) {
        let buffer_style = [...styling];
        let merged = [];

        let left_buffer = arr.slice(start, middle + 1);
        let right_buffer = arr.slice(middle + 1, end + 1);

        while (left_buffer.length > 0 && right_buffer.length > 0) {
            if (left_buffer[0] > right_buffer[0]) merged.push(right_buffer.shift());
            else merged.push(left_buffer.shift());
        }
        merged = merged.concat(left_buffer, right_buffer);
        for (let i = start, j = 0; i < end + 1; i++, j++) {
            setArr(prev => {
                let buffer_arr = [...prev];
                buffer_style[i] = "green";
                setStyling([...buffer_style]);
                buffer_arr[i] = merged[j];
                return buffer_arr;
            });

            await new Promise((resolve) => {
                setTimeout(() => {
                    resolve();
                }, speed);
            });
        }
    }
0

There are 0 answers