以下程序使用数组的第一个元素作为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));
问题/观察:
arr
变为[ 7, 2, 4, 5, 8 ]
而不是[ 5, 2, 4, 7, 8 ]
,其中分区索引是3(第4项)?
+ if (arr[partitionIndex] < arr[left]) {
[arr[partitionIndex], arr[left]] = [arr[left], arr[partitionIndex]];
+ }
答案 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));