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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 14:13:18