【问题标题】:What is wrong with this QuickSort implementation?这个 QuickSort 实现有什么问题?
【发布时间】:2011-12-14 08:06:10
【问题描述】:

我有以下几点:

function quickSort(array, low, high) {
    var len = array.length,
        l = low || 0,
        r = high || len - 1,
        m = Math.round((l + r) / 2),
        t;

    do {
        while (array[l] < array[m]) {
            l += 1;
        }
        while (array[r] > array[m]) {
            r -= 1;
        }

        if (l <= r) {
            if (l < r) {
                t = array[r];
                array[r] = array[l];
                array[l] = t;

                console.log('Swapped ' + array[r] + ' with ' +
                                         array[l] + '. ' +
                                         array);
            }

            l += 1;
            r -= 1;
        }
    } while (l <= r);

    if (r > 0) quickSort(array, 0, r);  
    if (l < len - 1) quickSort(array, l, len - 1);
}

如下使用:

var initial = [1, 8, 9, 0, 2, 5, 6, 7, 3, 4, 10], // Duplicate, just to compare
    sorted  = [1, 8, 9, 0, 2, 5, 6, 7, 3, 4, 10];

quickSort(sorted);

console.log('Initial: ' + initial + '\nSorted:  ' + sorted);

令人惊讶的是,代码在数组排序后抛出stack_overflow。我想我错过了递归退出条件,但我不知道在哪里。

【问题讨论】:

  • 您是否尝试过手动(手动)对列表进行排序并查看“已交换”日志行是否匹配。也许您可以在代码中添加一些 cmets(例如,为什么您有两个几乎相同的 if 嵌套?)。
  • @Lycha,是的,交换周期匹配。当我们到达if (l &lt;= r) 条件时,这意味着我们在left 一侧有一个大于分隔元素m 的元素。同样,我们还有一个小于m 的元素r。因此,我们交换它们,除非它们相等并增加(和减少)走廊边距。

标签: javascript sorting computer-science quicksort


【解决方案1】:

编辑(替换之前的答案):我相信这里的问题是您设置 len 变量的方式。对于就地排序,len 应该只是被排序的数组部分的长度,而不是整个数组,否则你最后的比较永远不会评估为假。所以而不是:

var len = array.length,
    l = low || 0,
    r = high || len - 1;

需要根据lr设置len

var l = low || 0,
    r = high || array.length - 1,
    len = r-l;

您可以在此处查看有效的 jsFiddle:http://jsfiddle.net/nrabinowitz/PPeh9/6/ - 我将您的测试数据替换为随机数组进行测试。

【讨论】:

  • 不,在这种情况下,数组的右边部分根本不会被排序——在do … while循环的末尾l将等于m - 1或@987654332 @。你可以在你提供的小提琴中检查它——部分排序的数组在 9 之后有 8。
  • @Honneykeepa - 你是对的,先生。我会再看一下这个 - 我确实认为这就是逻辑不正确的地方。
  • @Honneykeepa - 查看我的更新回复。此处的逻辑关闭,但这是因为 len 的设置方式,而不是您要比较的内容。
  • 这绝对是一个进步!点赞。但是,该函数不会对数组进行适当的排序。 @nrabinowitz,感谢您的时间和帮助。
  • 诅咒,你又是对的。这正在变成快速排序的速成课程。我再看看。 (出于好奇,您知道array.sort() 可能会明显更快,对吧?)
猜你喜欢
  • 2021-10-17
  • 2011-09-28
  • 2017-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-27
  • 2023-03-04
相关资源
最近更新 更多