首页 > web前端 > js教程 > 破解快速排序算法:几分钟内从理论到实践

破解快速排序算法:几分钟内从理论到实践

Susan Sarandon
发布: 2024-11-07 09:29:02
原创
434 人浏览过

快速排序是最快的排序算法之一。它采用一组值,选择其中一个值作为“枢轴”元素,并移动其他值,以便较低的值位于枢轴元素的左侧,较高的值位于其右侧。

快速排序是算法世界中最优雅、最高效的排序算法之一。与冒泡排序或选择排序等更简单的算法不同,快速排序采用复杂的分而治之策略,使其在实践中速度显着加快。虽然合并排序也使用分而治之,但快速排序独特的分区方法通常会带来更好的性能和内存使用。

平均时间复杂度:O(n log n)

最坏情况时间复杂度:O(n²)

空间复杂度:O(log n)

目录

  1. 什么是快速排序算法
  2. 快速排序是如何工作的
    • 时间复杂度
    • 空间复杂度
  3. JavaScript 实现
  4. 结论

什么是快速排序算法

快速排序是一种高效的排序算法,它的工作原理是从数组中选择一个“主元”元素,然后根据其他元素是否小于或大于主元将它们划分为两个子数组。与先划分后合并的归并排序不同,快速排序在划分过程中进行排序。

考虑与其他排序算法的比较:

Algorithm Time Complexity (Average) Space Complexity In-Place?
Quick Sort O(n log n) O(log n) Yes
Merge Sort O(n log n) O(n) No
Bubble Sort O(n²) O(1) Yes
Selection Sort O(n²) O(1) Yes
Heap Sort O(n log n) O(1) Yes

快速排序是如何工作的?

在深入研究快速排序算法的 JavaScript 实现之前,让我们通过四个简单步骤手动对简单的数字数组进行排序,逐步了解该算法的工作原理。

快速排序可以分为四个简单的步骤:

  1. 从数组中选择一个主元。该元素可以是列表/数组中的第一个、最后一个、中间的甚至是随机元素。
  2. 重新排列数组,使所有小于基准的元素位于左侧,所有大于基准的元素位于右侧。
  3. 将枢轴元素与值较大的第一个元素交换,使枢轴位于中间。
  4. 递归地将相同的操作应用于枢轴左侧和右侧的子数组。

让我们将这些步骤应用到真实的数组中。我们可以吗?

Cracking Quick Sort algorithm: From Theory to Practice in Minutes

初始数组: [3, 6, 2, 7, 1]

第 1 步:选择一个枢轴

  • 为了简单起见,我们选择最后一个元素作为枢轴。
  • 枢轴 = 1

第 2 步:围绕枢轴重新排列数组

  • 重新排列,使所有小于主元 (1) 的元素位于左侧,所有大于主元的元素位于右侧。
  • 当我们浏览每个元素时:
    • 3(大于 1)→ 保持在右侧。
    • 6(大于 1)→ 留在右侧。
    • 2(大于 1)→ 保持在右侧。
    • 7(大于 1)→ 保持在右侧。
  • 重新排列的数组: [1, 6, 2, 7, 3]

第 3 步:将枢轴交换到正确的位置

  • 将主元 (1) 与第一个大于它的元素(即 6)交换。
  • 交换后的数组: [1, 3, 2, 7, 6]
  • 现在,1 处于正确的位置(索引 0)。

第四步:子数组的递归快速排序

  • 左子数组: [](1 中没有剩下的元素,所以这里不需要排序)
  • 右子数组: [3, 2, 7, 6]

递归地对右子数组 [3, 2, 7, 6] 进行排序

第 1 步:选择一个枢轴

  • 枢轴 = 6(最后一个元素)

第 2 步:围绕枢轴重新排列数组

  • 将小于 6 的元素排列在左侧,将大于 6 的元素排列在右侧:
    • 3(小于 6)→ 留在左边。
    • 2(小于 6)→ 留在左边。
    • 7(大于 6)→ 留在右侧。
  • 重新排列的数组:[3,2,6,7]

第 3 步:将枢轴交换到正确的位置

  • 6 已经在正确的位置(索引 2)。
  • 数组: [1, 3, 2, 6, 7]

第四步:子数组的递归快速排序

  • 左子数组: [3, 2]
  • 右子数组:[7](单个元素,无需排序)

对左子数组 [3, 2] 进行排序

第 1 步:选择一个枢轴

  • 枢轴 = 2(最后一个元素)

第 2 步:围绕枢轴重新排列数组

  • 重新排列,使小于 2 的元素位于左侧:
    • 3(大于2)→ 留在右侧。
  • 重新排列的数组: [2, 3]

第 3 步:将枢轴交换到正确的位置

  • 2 已经处于正确位置(索引 1)。
  • 数组: [1, 2, 3, 6, 7]

第四步:子数组的递归快速排序

  • 左子数组:[](无元素)
  • 右子数组:[3](单个元素,无需排序)

最终排序数组

对所有子数组进行排序后,我们得到最终的排序数组:

排序数组: [1, 2, 3, 6, 7]

下面是在现实生活中如何运作的最佳说明:

Cracking Quick Sort algorithm: From Theory to Practice in Minutes

时间复杂度

快速排序的时间复杂度因主元选择而异:

  • 最佳情况(O(n log n)):

    • 当主元始终将数组分成相等的两半时发生
    • 类似于归并排序的性能
  • 平均情况 (O(n log n)):

    • 最实用的场景
    • 由于更好​​的缓存利用率而优于合并排序
  • 最坏情况 (O(n²)):

    • 发生在已经排序的数组和糟糕的主元选择
    • 可以通过良好的枢纽选择策略来避免

空间复杂度

快速排序的空间复杂度为 O(log n),因为:

  • 递归调用堆栈深度
  • 就地分区(与归并排序的 O(n) 额外空间不同)
  • 与归并排序相比,内存效率更高

JavaScript 实现

function quickSort(arr) {
  // Base case: arrays with length 0 or 1 are already sorted
  if (arr.length <= 1) return arr;

  // Helper function to swap elements
  const swap = (i, j) => {
    [arr[i], arr[j]] = [arr[j], arr[i]];
  };

  // Partition function using Lomuto's partition scheme
  function partition(low, high) {
    const pivot = arr[high];
    let i = low - 1;

    for (let j = low; j < high; j++) {
      if (arr[j] <= pivot) {
        i++;
        swap(i, j);
      }
    }
    swap(i + 1, high);
    return i + 1;
  }

  // Main quickSort function implementation
  function quickSortHelper(low, high) {
    if (low < high) {
      const pivotIndex = partition(low, high);
      quickSortHelper(low, pivotIndex - 1); // Sort left side
      quickSortHelper(pivotIndex + 1, high); // Sort right side
    }
  }

  quickSortHelper(0, arr.length - 1);
  return arr;
}
登录后复制

结论

快速排序因其效率和就地排序而成为流行的选择。它具有 O(n log n) 平均情况性能和低空间复杂度,优于冒泡排序和选择排序等更简单的算法。

要点:

  1. 谨慎选择枢纽选择策略
  2. 在快速排序和其他算法之间做出决定时考虑输入特征
  3. 使用随机主元选择以获得更好的平均情况性能


保持更新和联系

确保您不会错过本系列的任何部分,并与我联系以进行更深入的了解
关于软件开发(Web、服务器、移动或抓取/自动化)、数据的讨论
结构和算法,以及其他令人兴奋的技术主题,请关注我:

Cracking Quick Sort algorithm: From Theory to Practice in Minutes

伊曼纽尔·艾因德

软件工程师|技术撰稿人 |后端、网络和移动开发人员? |热衷于打造高效且可扩展的软件解决方案。 #让连接?
  • GitHub
  • 领英
  • X(推特)

敬请期待并祝您编码愉快??‍??

以上是破解快速排序算法:几分钟内从理论到实践的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板