在JS中快速排序

时间:2019-04-09 13:46:23

标签: javascript arrays quicksort

我在中等水平上发现了这个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.

我还必须完全了解代码的工作原理,但是您认为我所说的正确吗?

谢谢

1 个答案:

答案 0 :(得分:1)

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.

我怀疑作者在评论中犯了一个错误。应该说“分割索引处的元素”,而不是“分割索引右边的元素”。