algorithm-notes
  • Preface
  • Outline
    • Asymptotic-Analysis
    • Divide-and-Conquer (DnC)
      • Overview
      • Multiplication
      • DnC Strategy
      • Master Method
    • Randomization
      • Overview
      • Discrete Probability
      • Randomized Algorithms
      • Reservoir Sampling
    • Sorting
      • Overview
      • Selection Sort
      • Bubble Sort
      • Insertion Sort
      • Shell Sort
      • Merge Sort
      • Heap Sort
      • Quick Sort
      • Non-Comparison Sort
    • Graph Algorithms
      • Overview
      • Minimum Spanning Tree
      • Shortest Path
      • Topological Sort
    • Tree
      • Overview
      • Balanced Search Tree
        • AVL Tree
        • Red-Black Tree
        • B Tree
      • Heap
      • Disjoint Set
      • Threaded Binary Tree
      • Segment Tree
    • Searching
      • Overview
      • Binary Search
      • Graph Search
      • Hash Table
      • String Search
    • Dynamic Programming
      • Overview
      • Fibonacci Numbers
      • LCS problem
    • Greedy Algorithms
      • Overview
Powered by GitBook
On this page
  • Fundamental Ideas
  • Pseudocode
  • Partition Schemes
  • Lomuto Partition
  • Hoare Partition
  • Median-of-three (Mo3) Partition
  • Randomized Partition
  • Issues
  • Algorithm Analysis
  • Additional References

Was this helpful?

  1. Outline
  2. Sorting

Quick Sort

PreviousHeap SortNextNon-Comparison Sort

Last updated 6 years ago

Was this helpful?

Developed by early in 1950s, Quick Sort follows the DnC pattern but without the COMBINE phase in common DnC paradigm.

An animated example:

Fundamental Ideas

Given an input array of length n, choose a pivot in the array and partition around it in order that the left half of array has elements less than the value of the pivot while the right half of array has elements larger than the value of the pivot. It applies to all recursive calls with all sub-arrays until the base case in order that all elements are sorted in place.

Unlike the , is implemented in a style of sort-in-place with little extra memory usage. is prevalent in many practical applications and its running time Ο(n ⋅ log n) equates many of existing performant comparison-based implementations like .

Different partition methods incur distinct expected running time in total. It is widely adopted to use but the naive partition methods are still worth to study.

Pseudocode

QUICK_SORT(A, low, high)
  if low < high
    p := PARTITION(A, low, high)
    QUICK_SORT(A, low, p - 1)
    QUICK_SORT(A, p + 1, high)

Note: partition methods might vary in accordance with different inputs. Of many schemes, the is most recommended choice in practical use.

Partition Schemes

Lomuto Partition



LOMUTO_PARTITION(A, low, high)
  pivot := A[high]
  i := low - 1
  for j := low to high
    if A[j] ⩽ pivot
      i := i + 1
      if i ≠ j
        swap A[i] with A[j]
  return i

Hoare Partition

The fundamental idea is to always partition around the first element in the array. Two indices are used in both ends of the sub-arrays and progress towards each other to the middle until an inversion of a pair is found.



HOARE_PARTITION(A, low, high)
  pivot := A[low]
  i := low - 1
  j := high + 1
  loop
    do
      i := i + 1
    while A[i]  pivot

    if i ⩾ j
      return j

    swap A[i] with A[j]

Median-of-three (Mo3) Partition

Randomized Partition

Issues



QUICK_SORT(A, low, high)
  if low 

Algorithm Analysis

If every time the least or most value of sub-arrays been chosen as _pivot_s, the resulting complexity would be Ο(n2).

If every time the median value of the sub-array been chosen as pivot (best pivot), the resulting complexity would be Ο(n ⋅ log n). It still holds even if the pivot got chosen randomly in each run, what to be noted is there is no assumptions on data sets.

Proof:

  1. Define entry variable 𝓏i as the ith smallest element in the inputs.

  2. Then, the total number of entry comparisons:

wherein Pr(𝓏i compares 𝓏j) = Pr(𝓏i is chosen as the pivot) + Pr(𝓏j is chosen as the pivot) = 1 / (j-i+1) + 1 / (j-i+1) = 2 / (j-i+1)

complexity holds, proof ends.

Additional References

Lomuto Partition scheme chooses the last element from the array as the pivot as the recursion goes on. It is considered an introductory scheme for yet less efficient than scheme.

In the paper of written by Hoare, an original partition method is adopted.

A modest comparison of shows that Hoare partition runs three times smaller of swaps on average than Lomuto's.

Promoted by [Robert Sedgewick]()), the "median-of-three" scheme describes itself as choosing the median value among the first, last and middle elements of the array as the pivot.

It overcomes the problem of sorting almost sorted or reversely sorted arrays with a Ο(n2) by offering a relative "median" choice of an optimal pivot.

with a randomized partition is termed as the randomized QuickSort. It achieves an expected running time with an estimate of Ο(n ⋅ log n).

In the section of , an algorithm of randomized selection is introduced and its principle is chosen as the foundation to build the pivot selection subroutine of randomized QuickSort.

Quick sort is sometimes effortless in sorting task; given an almost sorted array, it is a waste of code execution for too many comparisons and not to mention that pivot choosing takes time. And is better in dealing with nearly sorted list.

Still, the quick sort scheme might inadvertently choose the least or most value of the sub-array in every recursion, resulting in a Ο(n2) comparisons. In other cases quick sort might be expecting to have efficiency of Ο(n ⋅ log n) given the medians of every sub-arrays are chosen in each iteration.

If there are duplicate elements in the array, or say elements with same value, standard quick sort routines won't work as brilliant as we expect. In a typical , a three-way partitioning routine is adopted to split the values into three groups: color of balls is red, color of balls is white and color of balls is black; Then, an improved should look like:

Note: the is not applicable here given that the subproblems are unbalanced and unpredictable.

Create an Xij = I{ 𝓏i compares 𝓏j }.

Apply ,

Summing up terms separately, the is obtained,

Why is quicksort better than other sorting algorithms in practice?

Quicksort
Hoare's and Lomuto's partition scheme
https://en.wikipedia.org/wiki/Robert_Sedgewick_(computer_scientist
worst-case
randomized algorithms
Insertion Sort
worst-case
master method
indicator random variable
linearity of expectation
asymptotic approximation
https://cs.stackexchange.com/questions/3/why-is-quicksort-better-than-other-sorting-algorithms-in-practice
Tony Hoare
Quick Sort Animation
Merge Sort
average-case
MergeSort
Quick Sort
Quick Sort
randomized partition
media-of-three
QuickSort
Hoare Partition
Quick Sort
Dutch National Flag problem
QuickSort