所以我对javascript很新(来自c)并开始学习语法,练习一些练习。我实现了一个快速排序算法:
function sort(a)
{
var _sort = function(l, r)
{
if (l >= r - 1)
return;
var p = r - 1;
var y = l;
var tmp;
for (var i = l; i < r - 1; i++)
if (a[i] < a[p])
{
tmp = a[i];
a[i] = a[y];
a[y] = tmp;
y++;
}
tmp = a[y];
a[y] = a[r - 1];
a[r - 1] = tmp;
_sort(l, y);
_sort(y + 1, r);
}
_sort(0, a.length);
}
它适用于小型数组,但是对于超过5000个元素的数组,我会超出堆栈大小限制。我试图增加它,但那不起作用。我怀疑我实现算法的方式有问题,可以吗?
我的问题是,我应该如何实现算法,或绕过堆栈大小限制(我认为5000元素数组很小),以使其工作?任何风格的建议我都会很高兴。
答案 0 :(得分:4)
您可以使用数组模拟堆栈,该数组可以更长。我用这个做了非常有限的测试,但它似乎有效。
function sort(a) {
var stack = [[0, a.length]];
while (1) {
var stackLength = stack.length;
if (! stackLength) {
break;
}
var l = stack[stackLength - 1][0],
r = stack[stackLength - 1][1];
if (l >= r - 1) {
stack.pop();
continue;
}
var p = r - 1;
var y = l;
var tmp;
for (var i = l; i < r - 1; i++)
if (a[i] < a[p])
{
tmp = a[i];
a[i] = a[y];
a[y] = tmp;
y++;
}
tmp = a[y];
a[y] = a[r - 1];
a[r - 1] = tmp;
stack.pop();
stack.push([y + 1, r]);
stack.push([l, y]);
}
return a;
}
答案 1 :(得分:4)
如您所知,对于已经排序或反向排序的输入,quicksort具有病态性能不佳的性能。在这些情况下,您最终会使用O(n)堆栈空间,这可能导致堆栈溢出错误。
为了避免这些问题,您可以选择枢轴元素“y”作为三个中间值(第一个,中间和最后一个),尽管显然有序列可以触发病理性能。要完全摆脱这个问题,您可以实现合并排序或堆排序。或者使用数组作为堆栈而不是使用递归。