setInterval在选择排序中失效求助:速度不受定时器参数影响
排序算法可视化问题:选择排序速度不受定时器控制
我在实现排序算法的可视化效果,冒泡排序运行正常,但选择排序的速度完全不受setInterval的time参数影响,不管怎么调整参数都保持同一速度。手动添加sleep能临时解决,但这并非合理方案。我试过将interval内的代码提取为外部函数、调整setInterval的位置,都无法实现正常的可视化效果,希望帮忙排查问题。
现有代码
冒泡排序
function bubbleSort(X, Y, LastX, LastY, no_loops, no_steps, time) { var i, j; var len = LastY.length; var isSwapped = false; for (i = 0; i < len; i++) { var intervalId = setInterval(function() { ctx.clearRect(0, 0, canvasElement.width, canvasElement.height); isSwapped = false; for (j = 0; j < len; j++) { if (LastY[j] > LastY[j + 1]) { var temp = LastY[j] LastY[j] = LastY[j + 1]; no_steps = no_steps + 1; LastY[j + 1] = temp; no_steps = no_steps + 1; isSwapped = true; } } drawArray(X, Y, LastX, LastY); no_loops = no_loops + 1; no_steps = no_steps + 1; document.getElementById("p1").innerHTML = no_loops; document.getElementById("p2").innerHTML = no_steps; if (isArraySorted(LastY) == true) { clearInterval(intervalId); } }, time); if (!isSwapped) { break; } } }
选择排序(存在问题)
function selectionSort(X, Y, LastX, LastY, no_loops, no_steps, time) { let n = LastY.length; for (let i = 0; i < n; i++) { var intervalId = setInterval(function() { ctx.clearRect(0, 0, canvasElement.width, canvasElement.height); let min = i; for (let j = i + 1; j < n; j++) { if (LastY[j] < LastY[min]) { min = j; } no_steps = no_steps + 1; } if (min != i) let tmp = LastY[i]; LastY[i] = LastY[min]; LastY[min] = tmp; no_steps = no_steps + 1; } drawArray(X, Y, LastX, LastY); //sleep(time); console.log(time); no_loops = no_loops + 1; no_steps = no_steps + 1; if (isArraySorted(LastY) == true) { return; } console.log(i); document.getElementById("p1").innerHTML = no_loops; document.getElementById("p2").innerHTML = no_steps; if (isArraySorted(LastY) == true) { clearInterval(intervalId); } }, time); }
问题排查与修复
核心问题
选择排序的外层for循环会瞬间创建n个setInterval定时器,这些定时器会同时触发执行排序逻辑,相当于所有排序步骤被并行执行,完全忽略了time参数设定的间隔,所以速度不受控制。
此外代码还存在语法错误:
if (min != i)后没有大括号,导致let tmp = LastY[i];仅在条件成立时执行,但后续的交换语句无论条件是否成立都会执行,引发逻辑错误console.log(time)后缺少分号,导致语法报错- 用
return终止排序无法清除定时器,会导致定时器继续运行
修复方案
改成异步步进式执行:只用一个定时器,每次触发时执行选择排序的一轮外层迭代(找到当前区间最小值并交换),完成后更新状态,直到数组排序完成再清除定时器。
修复后的选择排序代码:
function selectionSort(X, Y, LastX, LastY, no_loops, no_steps, time) { let n = LastY.length; let i = 0; // 用外部变量跟踪外层循环进度 const intervalId = setInterval(function() { if (i >= n || isArraySorted(LastY)) { clearInterval(intervalId); return; } ctx.clearRect(0, 0, canvasElement.width, canvasElement.height); let min = i; for (let j = i + 1; j < n; j++) { if (LastY[j] < LastY[min]) { min = j; } no_steps++; } // 修复交换逻辑的语法错误 if (min !== i) { const tmp = LastY[i]; LastY[i] = LastY[min]; LastY[min] = tmp; no_steps++; } drawArray(X, Y, LastX, LastY); no_loops++; no_steps++; document.getElementById("p1").textContent = no_loops; document.getElementById("p2").textContent = no_steps; i++; // 推进外层循环进度 }, time); }
额外优化提示
冒泡排序的现有写法也存在问题:外层for循环会创建多个setInterval,可能导致多个定时器同时运行。建议同样改成单定时器的步进式逻辑,避免潜在的异常。
内容的提问来源于stack exchange,提问作者Patryk Smoliński
相关产品推荐
相关产品推荐

