我在中等水平上找到了这个article,我试图弄清楚代码的实际作用。
这是代码:
帮手
const defaultComparator = (a, b) => {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
};
分类功能
const quickSort = (
unsortedArray,
comparator = defaultComparator
) => {
// Create a sortable array to return.
const sortedArray = [ ...unsortedArray ];
// Recursively sort sub-arrays.
const recursiveSort = (start, end) => {
// If this sub-array is empty, it's sorted.
if (end - start < 1) {
return;
}
const pivotValue = sortedArray[end];
let splitIndex = start;
for (let i = start; i < end; i++) {
const sort = comparator(sortedArray[i], pivotValue);
// This value is less than the pivot value.
if (sort === -1) {
// If the element just to the right of the split index,
// isn't this element, swap them.
if (splitIndex !== i) {
const temp = sortedArray[splitIndex];
sortedArray[splitIndex] = sortedArray[i];
sortedArray[i] = temp;
}
// Move the split index to the right by one,
// denoting an increase in the less-than sub-array size.
splitIndex++;
}
// Leave values that are greater than or equal to
// the pivot value where they are.
}
// Move the pivot value to between the split.
sortedArray[end] = sortedArray[splitIndex];
sortedArray[splitIndex] = pivotValue;
// Recursively sort the less-than and greater-than arrays.
recursiveSort(start, splitIndex - 1);
recursiveSort(splitIndex + 1, end);
};
// Sort the entire array.
recursiveSort(0, unsortedArray.length - 1);
return sortedArray;
};
因此,我花了一段时间来弄清楚
splitIndex
的工作原理。它从0开始,只有在for循环中的当前元素小于枢轴时,它才会递增1。当我们遇到大于枢轴值的数字时,splitIndex保持其值,并且i
递增。在下一步中,如果数字也小于轴数,我们将其交换因此,例如使用以下数组:
[2,4,65,1,15]
在for循环期间,splitIndex和i相等,直到获得数字65。在这里,splitIndex不递增,当我们到达数字1时,我们交换1和65。我不是英语母语人士,所以我不完全了解作者的意思:
// If the element just to the right of the split index,
// isn't this element, swap them.
我必须完全理解代码的工作原理,但是您认为我所说的正确吗?
谢谢
最佳答案
splitIndex
变量跟踪(在当前正在排序的数组部分中)比枢轴“小”和“等于或大”的元素之间的分隔线。您对其工作方式的描述似乎基本正确。
通常,如果遇到小于枢轴的元素,则将其与splitIndex
处的元素交换,以将其放入“小于枢轴”部分,然后递增splitIndex
表示该部分已扩大。如果遇到相等或更大的一个,则将其保留在原处,并且不要增大该部分。
假设splitIndex
处的元素不小于枢轴,这是有道理的。如果i
大于splitIndex
,这是正确的,因为那时我们已经遇到了至少一个这样的元素,并跳过了它。
例外是,如果我们当前正在检查splitIndex
处的元素(只要到目前为止的所有元素都小于透视点,情况就是如此)。在这种情况下,我们将交换元素本身。这是多余的,因此这就是splitIndex !== i
检查的原因。
至于
// If the element just to the right of the split index,
// isn't this element, swap them.
我怀疑作者在评论中犯了一个错误。应该说“分割索引处的元素”,而不是“分割索引右边的元素”。