为什么在第一次调用getPartitionIndex时没有正确返回partitionIndex?

时间:2018-03-30 00:44:29

标签: javascript algorithm quicksort

以下程序使用数组的第一个元素作为pivot进行排序,但getParitionIndex不能按预期工作。最后给出的具体问题/意见。

var quickSort = function (arr, left, right) {
    if (left < right) {
        const partitionIndex = getPartitionIndex(arr, left, right);
            quickSort(arr, left, partitionIndex-1);
            quickSort(arr, partitionIndex+1, right);
    }
    return arr;

}

var getPartitionIndex = function (arr, left, right) {
    let pivot = arr[left], // Left most element is pivot
        partitionIndex = left + 1, // Since, left is the pivot
        i;

    for (i = left + 1; i <= right; i++) {
        if (arr[i] < pivot) {
            [arr[partitionIndex], arr[i]] = [arr[i], arr[partitionIndex]];
            partitionIndex++;
        }
    }
    [arr[partitionIndex], arr[left]] = [arr[left], arr[partitionIndex]];

    return partitionIndex;
}

// Test 1
console.log(quickSort([5,2,8,7,4], 0, 4));

问题/观察:

  1. 为什么在第一次调用getPartitionIndex之后,arr变为[ 7, 2, 4, 5, 8 ]而不是[ 5, 2, 4, 7, 8 ],其中分区索引是3(第4项)?
  2. 如果我进行以下更改以获得#1中提到的所需输出,那么即使程序在达到最大调用堆栈大小时也会失败。
  3. + if (arr[partitionIndex] < arr[left]) {
            [arr[partitionIndex], arr[left]] = [arr[left], arr[partitionIndex]];
    + }

1 个答案:

答案 0 :(得分:0)

partitionIndex超越了最后一个元素&lt;枢。修正案在评论中提到。您可能想要查看wiki伪代码。它使用hi / right进行透视,但想法是一样的。

https://en.wikipedia.org/wiki/Quicksort#Lomuto_partition_scheme

Hoare分区方案通常更快。请注意,对于标准Hoare分区方案,pivot元素最终位于左子阵列的右端或右子阵列的左端。可以添加额外的代码来隔离枢轴元素,类似于Lomuto方案:

https://en.wikipedia.org/wiki/Quicksort#Hoare_partition_scheme

var quickSort = function (arr, left, right) {
    if (left < right) {
        partitionIndex = getPartitionIndex(arr, left, right);
        quickSort(arr, left, partitionIndex-1);
        quickSort(arr, partitionIndex+1, right);
    }
    return arr;
}

var getPartitionIndex = function (arr, left, right) {
    let pivot = arr[left],
        partitionIndex = left,    // fix
        i;

    for (i = left + 1; i <= right; i++) {
        if (arr[i] < pivot) {
            partitionIndex++;     //fix
            [arr[partitionIndex], arr[i]] = [arr[i], arr[partitionIndex]];
        }
    }
    [arr[partitionIndex], arr[left]] = [arr[left], arr[partitionIndex]];

    return partitionIndex;
}

// Test 1
console.log(quickSort([5,2,8,7,4], 0, 4));