javascript - 为什么在此快速排序期间超出了我的调用堆栈大小?
问题描述
当我尝试在 JS 中实现快速排序时出了什么问题?我收到超出调用堆栈大小的错误。
function quicksort(arr) {
if (arr.length <= 1)
return arr;
let pivot = Math.floor(arr.length / 2);
const left = [], right = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
}
else {
right.push(arr[i]);
}
}
return quicksort(left).concat(pivot, quicksort(right));
}
console.log(quicksort([2, 5, 9, 5, 67, 1, 23, 9]));
解决方案
当您的代码构建left
andright
数组时,该过程包括枢轴值。因此,这两个子数组的总长度与原始数组的总长度相同。
如果您跳过枢轴元素,则排序有效(至少对于您的测试用例):
function quicksort(arr) {
if (arr.length <= 1)
return arr;
let pp = Math.floor(arr.length / 2), pivot = arr[pp];
const left = [], right = [];
for (var i = 0; i < arr.length; i++) {
if (i == pp) continue;
if (arr[i] < pivot) {
left.push(arr[i]);
}
else {
right.push(arr[i]);
}
}
return quicksort(left).concat(pivot, quicksort(right));
}
console.log(quicksort([2, 5, 9, 5, 67, 1, 23, 9]));
正如我在上面的评论中所指出的,快速排序在其他优秀排序算法中的一个关键特性是它可以通过恒定的空间开销来完成。实际实现不会创建新的子数组。相反,它们重新排列原始数组中的元素。递归步骤包括开始和结束索引,而不是完整的新数组。
推荐阅读
- kubernetes - 从部署配置中配置 pod 的重启策略
- json - Asp.net 核心 webapi 类属性 IList
- > 只返回一级属性
- azure - ADF V2 显式映射
- azure-databricks - 从 ADLS Gen2 错误读取文件 - 找不到配置属性 xxx.dfs.core.windows.net
- reactjs - GET http://localhost:8000/index.js net::ERR_ABORTED 404(未找到)
- c# - 使用私有构造函数对类进行单元测试
- c# - 如何将内容不同但结构相同的 JSON 字符串转换为 C# 对象?
- api - 通过 API 的 ReleasePayment 导致 PX.Data.PXActionDisabledException
- android - 如何检测已弃用的 androidx.legacy.widget.Space 类?
- python - 无法单独绘制箱线图