You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修复Bubble Sort算法提前终止问题:实现数据集排序完成后停止

解决冒泡排序异步提前终止问题

问题根源

原代码中,外层for循环是同步执行的,而元素比较、交换的逻辑被包裹在setTimeout中异步执行。当第一轮i循环结束后,同步代码会立刻检查changed变量——但此时所有异步的比较/交换操作还没执行,changed仍为初始的false,导致函数直接return,排序仅完成一次迭代就提前终止。

修改方案

核心思路是将每一轮排序的结束判断(是否继续下一轮)放到异步队列的最后,确保只有当当前轮所有元素的比较、交换操作全部完成后,才检查changed并决定是否继续排序。我们可以用递归替代外层的同步for循环,让每一轮排序的启动依赖上一轮的完成。

修改后的完整代码

// Sort the elements using Bubble Sort
function bubble_sort() {
    sort.addEventListener("click", function() {
        const dataList = document.querySelectorAll(".data");
        let delay = 0;
        const totalElements = dataList.length;

        // 递归处理每一轮冒泡排序
        function runBubbleRound(i) {
            if (i >= totalElements - 1) return; // 所有轮次完成,退出
            let changed = false;
            const currentRoundDelay = delay; // 记录当前轮的初始延迟

            for (let j = 0; j < totalElements - 1 - i; j++) {
                setTimeout(() => {
                    let value1 = parseInt(dataList[j].getAttribute("value"));
                    let value2 = parseInt(dataList[j + 1].getAttribute("value"));

                    // 高亮当前比较的元素对
                    dataList[j].style.backgroundColor = "blue";
                    dataList[j + 1].style.backgroundColor = "blue";

                    if (value1 > value2) {
                        // 交换高度和value属性
                        let tempHeight = dataList[j].style.height;
                        let tempValue = dataList[j].getAttribute("value");

                        dataList[j].style.height = dataList[j + 1].style.height;
                        dataList[j].setAttribute("value", dataList[j + 1].getAttribute("value"));

                        dataList[j + 1].style.height = tempHeight;
                        dataList[j + 1].setAttribute("value", tempValue);
                        changed = true;
                    }

                    // 延迟恢复元素颜色
                    setTimeout(() => {
                        dataList[j].style.backgroundColor = "black";
                        dataList[j + 1].style.backgroundColor = "black";
                    }, speed / 2);

                }, delay);
                
                delay += speed;
            }

            // 等待当前轮所有操作完成后,检查是否需要继续下一轮
            setTimeout(() => {
                if (changed) {
                    runBubbleRound(i + 1); // 有交换,继续下一轮
                }
                // 无交换则直接终止排序
            }, currentRoundDelay + (totalElements - 1 - i) * speed);
        }

        // 启动第一轮排序
        runBubbleRound(0);
    });
}

关键修改点

  • 用递归函数runBubbleRound替代外层同步for循环,每一轮排序的启动由上一轮的结束判断触发
  • 将changed的检查逻辑放到setTimeout中,延迟时间设置为当前轮所有操作的总耗时(currentRoundDelay + (totalElements - 1 - i) * speed),确保当前轮所有异步操作完成后才判断是否继续
  • 记录当前轮的初始延迟currentRoundDelay,避免后续delay累加影响当前轮的结束判断时间

内容的提问来源于stack exchange,提问作者That wolphin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 02:17:16