通过 JavaScript 理解快速排序

合并类型合作的一个问题是,他们需要在内存中创建和存储大量的数组,其中大部分是多余的数据。

前提条件

我们将讨论标准回归版本,尽管你可以重复地做到这一点,所以了解回归如何工作将是有帮助的,你可以在这里(https://andsky.com/tech/tutorials/js-understanding-recursion)刷。

概念

快速排序绝对是最不直观的算法之一,所以这里有一个非常简单的概述。

我们选择一个数字,称为我们的旋转,我们将将每一个数字与它进行比较,当我们通过我们的项目旋转时。目标是重新组织数组,以便它分为两半,每个项目中的每件事都小于或大于我们的旋转。

Quick Sort Animation

图形 / 动画 通过 VisuAlgo.net

就像 merge 类一样,平均复杂度为 O(nlogn),所以你选择哪个是你的选择。

实践数据

像往常一样,这里有一个50个随机数字的未分类数组,我还建议看看JavaScript的 性能 api以与其他算法和不同的数据进行比较。

1const unsortedArr = [31, 27, 28, 42, 13, 8, 11, 30, 17, 41, 15, 43, 1, 36, 9, 16, 20, 35, 48, 37, 7, 26, 34, 21, 22, 6, 29, 32, 49, 10, 12, 19, 24, 38, 5, 14, 44, 40, 3, 50, 46, 25, 18, 33, 47, 4, 45, 39, 23, 2];

皮尔

首先,我们需要我们的旋转实用函数,有4个主要部分,我们的交换器,循环,旋转本身和我们的指针。

我们的指针仅仅是我们旋转的站点。每次我们的循环进展时,每个项目都与旋转进行比较,如果小,则与我们的旋转器进行交换。每次我们这样做,就是确保旋转器在比旋转更小的东西和更大的东西前面。当一切都完成了,我们的阵列被分割了,那么我们可以将旋转器分配给旋转器的索引作为其最终位置。

我们的交换工作只是将每个项目的索引重新分配到对方的索引中,没有什么太疯狂的。

 1const pivot = (arr, start = 0, end = arr.length + 1) => {
 2  const swap = (list, a, b) => [list[a], list[b]] = [list[b], list[a]];
 3
 4  let pivot = arr[start],
 5      pointer = start;
 6
 7  for (let i = start; i < arr.length; i++) {
 8    if (arr[i] < pivot  ) {
 9      pointer++;
10      swap(arr, pointer, i);
11    }
12  };
13  swap(arr, start, pointer);
14
15  return pointer;
16}

快速黑色

我们将使用我们的函数从我们的数组中获取第一个分类项目. 这样,我们将重复运行我们的quickSort,在我们分割数组的第一半部分执行相同的过程,这将重复,直到没有剩下什么可分类,然后对另一半做同样的事情. 当两者完成时,我们的完全分类数组可以返回。

 1const quickSort = (arr, start = 0, end = arr.length) => {
 2  let pivotIndex = pivot(arr, start, end);
 3
 4  if (start >= end) return arr;
 5  quickSort(arr, start, pivotIndex);
 6  quickSort(arr, pivotIndex + 1, end);
 7
 8  return arr;
 9};
10
11console.log(quickSort(unsortedArr));

结论

快速排序绝对是最困难的排序算法之一,把我的头包围起来。在有4个变更部分和2个回归堆栈之间,这绝对是你可能不应该期望完全记住的东西,并且可能想为以后的参考打字。

Published At
Categories with 技术
Tagged with
comments powered by Disqus