Fancy DSA Fancy DSA
数据结构
算法
LeetCode
  • 关于
  • 导航 (opens new window)
  • 分类
  • 标签
  • 归档
设计模式 (opens new window)
博客 (opens new window)
GitHub (opens new window)

Jonsam NG

想的更多,也要想的更远
数据结构
算法
LeetCode
  • 关于
  • 导航 (opens new window)
  • 分类
  • 标签
  • 归档
设计模式 (opens new window)
博客 (opens new window)
GitHub (opens new window)
  • 开始上手
  • Plan 计划
  • Roadmap 路线
  • 算法简介
  • Sort 排序

    • 章节概要
    • AlphaNumericalSort [字母顺序排序]
    • BeadSort [珠排序]
    • BogoSort [Bogo 排序]
    • BubbleSort [冒泡排序]
    • BucketSort [桶排序]
    • CocktailShakerSort [鸡尾酒排序]
    • CombSort [梳排序]
    • CountingSort [计数排序]
    • CycleSort [圈排序]
    • FisherYatesShuffle [洗牌算法]
    • FlashSort [闪电排序]
    • GnomeSort [侏儒排序]
    • HeapSort [堆排序]
    • InsertionSort [插入排序]
    • IntroSort [内省排序]
    • MergeSort [归并排序]
    • OddEvenSort [奇偶排序]
    • PancakeSort [煎饼排序]
    • PigeonHoleSort [鸽巢排序]
    • QuickSort [快速排序]
      • 介绍
      • 原理
      • 伪代码
      • 动画
      • 实现
      • 参考
    • RadixSort [基数排序]
    • SelectionSort [选择排序]
    • ShellSort [希尔排序]
    • TimSort [Tim 排序]
    • TopologicalSorter [拓扑排序器]
    • WiggleSort [摆动排序]
  • Search 搜索

  • Recursive 递归

  • Graph 图

  • Tree 树

  • Math 数学

  • Hash 哈希

  • String 字符串

  • BitManipulation 位操纵

  • Backtracking 回溯

  • DynamicProgramming 动态规划

  • Cache 缓存

  • Array 数组

  • Ciphers 密码学

  • Conversions 转换

  • ProjectEuler 欧拉计划

  • 其他

  • 算法
  • Sort 排序
jonsam
2022-04-26
目录

QuickSort [快速排序]

# 介绍

快速排序(英语:Quicksort),又称分区交换排序(partition-exchange sort),简称快排,一种排序算法,最早由东尼・霍尔提出。在平均状况下,排序 n 个项目要 O(nlog⁡n){\displaystyle \ O(n\log n)}O(nlogn)(大 O 符号)次比较。在最坏状况下则需要 O(n2){\displaystyle O(n^{2})}O(n2) 次比较,但这种状况并不常见。事实上,快速排序 Θ(nlog⁡n){\displaystyle \Theta (n\log n)}Θ(nlogn) 通常明显比其他算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地达成。

# 原理

快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为较小和较大的 2 个子序列,然后递归地排序两个子序列。

步骤为:

  • 挑选基准值:从数列中挑出一个元素,称为 “基准”(pivot),
  • 分割:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以到任何一边)。在这个分割结束之后,对基准值的排序就已经完成,
  • 递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。
  • 递归到最底部的判断条件是数列的大小是零或一,此时该数列显然已经有序。

选取基准值有数种具体方法,此选取方法对排序的时间性能有决定性影响。

# 伪代码

function quicksort(q) {
     var list less, pivotList, greater
     if length(q) ≤ 1 return q
     else {
         select a pivot value pivot from q
         for each x in q except the pivot element {
             if x < pivot then add x to less
             if x ≥ pivot then add x to greater
         }
         add pivot to pivotList
         return concatenate(quicksort(less), pivotList, quicksort(greater))
     }
 }
1
2
3
4
5
6
7
8
9
10
11
12
13

# 动画

# 实现

# JavaScript

/**
 * @function QuickSort
 * @description Quick sort is a comparison sorting algorithm that uses a divide and conquer strategy.
 * @param {Integer[]} items - Array of integers
 * @return {Integer[]} - Sorted array.
 * @see [QuickSort](https://en.wikipedia.org/wiki/Quicksort)
 */
function quickSort (items) {
  const length = items.length

  if (length <= 1) return items
  const PIVOT = items[0]
  const GREATER = []
  const LESSER = []

  for (let i = 1; i < length; i++) {
    if (items[i] > PIVOT) GREATER.push(items[i])
    else LESSER.push(items[i])
  }

  return [...quickSort(LESSER), PIVOT, ...quickSort(GREATER)]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# QuickSortRecursive

/*
    Quicksort is the most popular sorting algorithm and there have
    lots of different implementations but the "recursive" or "Partition in place"
    is one of the most efficient implementations below we have discussed how to
    implement it.
    Partition in place => "in place" Partition in place indicates that we
    do not need any other space to store the auxiliary array and the term
    "partition" denotes that we split the list into two parts one is less
    than the pivot and the other is greater than the pivot and repeats this
    process recursively and breaks the problem into sub-problems and makes
    it singular so that the behavior or "divide and conquer" get involved
    too.
    Problem & Source of Explanation => https://www.cs.auckland.ac.nz/software/AlgAnim/qsort1a.html
*/

/**
 * Partition in place QuickSort.
 * @param {number[]} inputList list of values.
 * @param {number} low lower index for partition.
 * @param {number} high higher index for partition.
 */
const quickSort = (inputList, low, high) => {
  if (!Array.isArray(inputList)) {
    throw new TypeError('Please input a valid list or array.')
  }
  if (low < high) {
    // get the partition index.
    const pIndex = partition(inputList, low, high)
    // recursively call the quickSort method again.
    quickSort(inputList, low, pIndex - 1)
    quickSort(inputList, pIndex + 1, high)
  }
  return inputList
}

/**
 * Partition In Place method.
 * @param {number[]} partitionList list for partitioning.
 * @param {number} low lower index for partition.
 * @param {number} high higher index for partition.
 * @returns {number} `pIndex` pivot index value.
 */
const partition = (partitionList, low, high) => {
  const pivot = partitionList[high]
  let pIndex = low
  for (let index = low; index <= high - 1; index++) {
    if (partitionList[index] < pivot) {
      // swap variables using array destructuring
      [partitionList[index], partitionList[pIndex]] = [partitionList[pIndex], partitionList[index]]
      pIndex += 1
    }
  }
  [partitionList[pIndex], partitionList[high]] = [partitionList[high], partitionList[pIndex]]
  return pIndex
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

# 参考

  • 快速排序 - 维基百科,自由的百科全书 (opens new window)
编辑 (opens new window)
上次更新: 2022/10/28, 17:23:56
PigeonHoleSort [鸽巢排序]
RadixSort [基数排序]

← PigeonHoleSort [鸽巢排序] RadixSort [基数排序]→

最近更新
01
0-20题解
10-31
02
本章导读
10-31
03
算法与转换:Part1
10-28
更多文章>
Theme by Vdoing | Copyright © 2022-2022 Fancy DSA | Made by Jonsam by ❤
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式