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

JavaScript递归选择排序递归退出问题:栈溢出错误求助

解决递归选择排序的栈溢出问题

看起来你卡在递归终止条件上啦!这个栈溢出错误(Uncaught RangeError: Maximum call stack size exceeded)几乎都是因为递归没有正确的退出逻辑,导致函数无限调用自己,把调用栈撑爆了。

先帮你补全没写完的findSmallestIndex函数,这部分逻辑是对的,只是缺了返回值:

const findSmallestIndex = (arr) => {
  let smallest = arr[0];
  let smallestIndex = 0;
  const arrLen = arr.length;
  for (let i = 0; i < arrLen; i++) {
    if (arr[i] < smallest) {
      smallest = arr[i];
      smallestIndex = i;
    }
  }
  return smallestIndex; // 这里要返回找到的最小元素索引
};

接下来是递归选择排序的核心问题:必须给递归加终止条件。当数组长度小于等于1时,它本身已经是有序的,直接返回就行,不需要再递归。然后每次递归处理的是「去掉当前最小元素后的剩余数组」,这样数组长度会逐渐缩小,最终触发终止条件。

给你两种实现方式,按需选择:

方式1:不修改原数组(更安全)

这种方式用slice复制数组,不会改变传入的原数组:

const selectionSort = (arr) => {
  // 递归终止条件:数组为空或只有一个元素时直接返回
  if (arr.length <= 1) return [...arr];

  const smallestIndex = findSmallestIndex(arr);
  const smallest = arr[smallestIndex];
  // 生成去掉最小元素后的新数组
  const remainingArr = [...arr.slice(0, smallestIndex), ...arr.slice(smallestIndex + 1)];
  
  // 递归处理剩余数组,把最小元素放在最前面
  return [smallest, ...selectionSort(remainingArr)];
};

方式2:使用splice修改数组(更高效,但会改变原数组)

如果不在意原数组被修改,可以用splice直接取出最小元素,减少一次数组复制:

const selectionSort = (arr) => {
  if (arr.length <= 1) return [...arr];

  const smallestIndex = findSmallestIndex(arr);
  // 取出最小元素,同时修改原数组去掉这个元素
  const [smallest] = arr.splice(smallestIndex, 1);
  
  return [smallest, ...selectionSort(arr)];
};

为什么之前会栈溢出?

如果你的selectionSort函数没有判断arr.length <= 1,那么即使数组只剩最后一个元素,函数还是会继续调用自己,陷入无限递归,直到调用栈达到浏览器的上限,就会抛出那个错误。

测试一下,比如调用selectionSort([5,3,6,2,10]),就能得到升序排列的[2,3,5,6,10]啦!

内容的提问来源于stack exchange,提问作者Ann Pavlov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:13:16