简体   繁体   中英

Array not being updated after switching indexs

I'm working on a visualizer for sorting algorithms. Everything is working as intended until I got to the Selection Sort. I understand that the Selection sort will make a pass and search for the MINIMUM value and then swap that the index that it started at in the array. However, each time it makes a pass, the i value doesn't change. I tested it by changing the color of the block the i index represents in my loop and it never changes, so the MINIMUM value just keeps switching to where ever the i is. You can view my project here on GitHub Pages, just use the left Navbar to choose Selection Sort and you can see the problem I'm having. The bottom snippet is my swap function, it didn't do this with any of the other sort methods, only the selection sort.

Github Pages -- https://kevin6767.github.io/sorting-algorithm-visualization/

Selection function

async function selectionSort() {
    let blocks = document.querySelectorAll('.block');

    for (let i = 0; i < blocks.length; i++) {
        // Assume a minimum value
        let min = i;
        for (let j = i + 1; j < blocks.length; j++) {
            blocks[j].style.backgroundColor = '#FF4949';
            blocks[min].style.backgroundColor = '#13CE66';
            blocks[i].style.backgroundColor = 'orange';

            await new Promise((resolve) =>
                setTimeout(() => {
                    resolve();
                }, frame_speed)
            );
            const value1 = Number(blocks[j].childNodes[0].innerHTML);
            const value2 = Number(blocks[min].childNodes[0].innerHTML);
            if (value1 < value2) {
                blocks[min].style.backgroundColor = '#58B7FF';
                min = j;
            }
            blocks[j].style.backgroundColor = '#58B7FF';
        }
        if (min !== i) {
            let tmp = blocks[i];
            blocks[i] = blocks[min];
            blocks[min] = tmp;
            await swap(blocks[i], blocks[min]);
            blocks = document.querySelectorAll('.block');
        }
        // Swap if new minimun value found
        blocks[i].style.backgroundColor = '#58B7FF';
    }
}

Swap function

function swap(el1, el2) {
    return new Promise((resolve) => {
        const style1 = window.getComputedStyle(el1);
        const style2 = window.getComputedStyle(el2);

        const transform1 = style1.getPropertyValue('transform');
        const transform2 = style2.getPropertyValue('transform');

        el1.style.transform = transform2;
        el2.style.transform = transform1;

        // Wait for the transition to end!
        window.requestAnimationFrame(function () {
            setTimeout(() => {
                container.insertBefore(el2, el1);
                resolve();
            }, 300);
        });
    });
}

I ended up fixing it. It seems that I had to take the Nodelist array I was getting from just.querySelectorAll and convert that into an array using.Arrayfrom() which was pretty simple after some googling. From then on I needed to figure out how to update the array each pass, which once again was as simple as just moving one index from another.

The interesting part of the answer was how I was going to update the Nodelist itself that way all my css code would still work (This is a sorting visualizer, so it would show you what element it was on and highlight it with a color). The answer however was right in front of me. Even though I turned the Nodelist array into a regular array, I was still able to apply styles to it. This meant I didn't have to mutate the Nodelist array at all and was just able to keep a seperate array within the function to work with.

PS. The algorithm did have a lot of trouble in the above snippet because I was comparing 2 strings in the if statement (value1 and value2) this is what caused a lot of the actual algorithm erroring and was simply fixed by adding a Number() function around my innerhtml code.

Selection

async function selectionSort() {
    let blocks = document.querySelectorAll('.block');
    let convertedBlocks = Array.from(blocks);
    let len = convertedBlocks.length;
    for (let i = 0; i < len; i++) {
        let min = i;
        for (let j = i + 1; j < len; j++) {
            convertedBlocks[j].style.backgroundColor = 'red';
            convertedBlocks[min].style.backgroundColor = 'green';
            convertedBlocks[i].style.backgroundColor = 'orange';
            await new Promise((resolve) =>
                setTimeout(() => {
                    resolve();
                }, frame_speed)
            );
            if (
                Number(convertedBlocks[min].childNodes[0].innerHTML) >
                Number(convertedBlocks[j].childNodes[0].innerHTML)
            ) {
                convertedBlocks[min].style.backgroundColor = '#58B7FF';
                min = j;
            }
            convertedBlocks[j].style.backgroundColor = '#58B7FF';
        }
        if (min !== i) {
            let tmp = convertedBlocks[i];
            convertedBlocks[i] = convertedBlocks[min];
            convertedBlocks[min] = tmp;
            await swap(convertedBlocks[i], convertedBlocks[min]);
        }
        convertedBlocks[min].style.backgroundColor = '#58B7FF';
        convertedBlocks[i].style.backgroundColor = '#58B7FF';
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM