JavaScript快速排序中的无限递归
Infinite recursion in JavaScript quicksort?
这是我编写的快速排序代码。函数无法工作,因为它无法到达基本情况。如果我将pivot、r
和l
记录到控制台,那么无论调用多少次排序函数,它们都保持不变。所以我想知道参数l
、r
是否真的作为数据传递到函数中。为什么会发生这种事?
function sort(data){
if(data.length < 2){
return data;
}
else{
var l = [];
var r = [];
var pivot = parseInt(data.length/2);
for(i=0; i<data.length; i++){
if(data[i] > data[pivot]){
r.push(data[i]);
}
else{
l.push(data[i]);
}
}
return sort(l).concat(sort(r));
}
}
我认为这里的问题是分区步骤不一定会缩小输入数组。例如,让我们跟踪一下如果您尝试排序[1,2]会发生什么。在这种情况下,您的枢轴元素将是元素2。由于1>2为假,则将1添加到列表l
。由于2>则2被添加到列表l
。因此,列表l
上的递归调用将具有与原始调用完全相同的参数,从而导致无限递归。
要解决此问题,请尝试将输入拆分为三个列表——一个较小的值,一个相等的值,以及一个较大的值。此代码显示在此处:
function sort(data){
if (data.length < 2){
return data;
} else {
var l = [];
var r = [];
var e = [];
var i = 0;
var pivot = (data.length / 2) | 0;
for(i = 0; i < data.length; i++) {
if (data[i] > data[pivot]) {
r.push(data[i]);
} else if (data[i] < data[pivot]) {
l.push(data[i]);
} else {
e.push(data[i]);
}
}
return sort(l).concat(e, sort(r));
}
}
这个新版本显式地将相等的元素分组到它们自己的列表中,因此它们不会通过任何递归调用进行递归排序。它还优雅地处理重复的元素。
如果选择数组中最大的值作为pivot元素,则data
的所有值都将出现在数组l
中,而r
中没有任何值。因此,将使递归永远不会停止(并使l
、r
和pivot
保持相同的值)。除非这是一项脑力锻炼,否则使用data.sort()
应该会做得更好。)
JavaScript通过引用传递对象(数组也是对象)。如果要按值传递它们,则需要使用此处解释的拼接函数。
请注意,这将创建大量数据副本。您可能想要使用本机sort()函数。
相关文章:
- 数组在递归方法中设置为null
- Kendo:我该如何在树视图中创建一个递归的hieiarchy
- 递归使用 eval() 是检查程序执行的好方法吗?
- 使用递归、Ramda.js和无点样式重构字符串的getPermutations()
- JavaScript 素数搜索无限递归
- 挖空.js映射导致 IE9 上的无限递归
- 不使用递归创建jquery无限动画
- 检测无限递归
- Javascript窗口树递归和无限对象
- AngularJS和ui视图导致无限递归
- 无限循环与递归javascript函数
- Javascript中产生无限循环的递归函数
- jQuery无限递归当字符串调用DOM上添加的元素上的插件时
- 在node.js中,全局变量的值在堆栈被无限递归超越后神秘地重置
- Javascript递归承诺陷入无限循环
- Java脚本递归地添加子节点以无限循环结束
- 没有无限循环地递归成对象
- JavaScript快速排序中的无限递归
- 为什么这些符号链接会发生无限递归循环
- (为什么)有一个“自称”的指令在一个有限的n -repeat导致一个堆栈溢出从无限递归