Previous Topic
overview
0.92
Establishes the vocabulary and evaluation criteria (time/space complexity, stability, in-place) that frame the study of specific algorithms like quick sort.
baseline_comparison_sort
0.78
Provides a simple, stable, in-place reference that highlights why quick sort’s partitioning strategy achieves better performance.
basic_algorithm
0.75
Insertion Sort is a fundamental sorting technique that lays the groundwork for understanding more advanced algorithms like Quick Sort.

Quick Sort

algorithms data structures sorting algorithms divide and conquer recursion performance computer science
Quick Sort is a divide-and-conquer comparison sorting algorithm that partitions a list around a pivot element, then recursively sorts the sublists on either side of the pivot. It runs in average O(n log n) time, is typically in-place and cache-friendly, but has a worst-case time of O(n^2) without careful pivot selection or fallback strategies. It is widely used in practice due to excellent average performance and small constant factors.

What Is Quick Sort?

Quick Sort is a fast, general-purpose sorting algorithm that works by picking a pivot, partitioning the array into elements less than (or equal to) and greater than the pivot, and then recursively sorting the partitions. It is a classic example of the divide-and-conquer paradigm.

Key Ideas

  • Divide-and-conquer: Split the problem into smaller subproblems, solve them recursively, and combine (implicitly via partitioning).
  • Partitioning: Rearrange elements so that all items left of the pivot are less than or equal to it, and all items right are greater.
  • In-place (typically): Uses constant extra space for partitioning, with additional space from recursion.
  • Average-case efficiency: Runs in O(n log n) on average, which is competitive with other efficient sorts.

Algorithm Outline

  1. Choose a pivot element from the array (e.g., last, first, random, or median-of-three).
  2. Partition the array around the pivot.
  3. Recursively apply Quick Sort to the left and right partitions.

Pseudocode (Lomuto Partition)

function partition(A, lo, hi):
    pivot = A[hi]
    i = lo
    for j = lo to hi - 1:
        if A[j] <= pivot:
            swap A[i], A[j]
            i = i + 1
    swap A[i], A[hi]
    return i

function quick_sort(A, lo, hi):
    if lo >= hi:
        return
    p = partition(A, lo, hi)
    quick_sort(A, lo, p - 1)
    quick_sort(A, p + 1, hi)

Alternative Partition: Hoare Scheme

Hoare's partition can perform fewer swaps and is often faster, especially with many equal keys.

function partition_hoare(A, lo, hi):
    pivot = A[(lo + hi) // 2]
    i = lo - 1
    j = hi + 1
    while true:
        repeat:
            i = i + 1
        until A[i] >= pivot
        repeat:
            j = j - 1
        until A[j] <= pivot
        if i >= j:
            return j
        swap A[i], A[j]

function quick_sort_hoare(A, lo, hi):
    if lo < hi:
        p = partition_hoare(A, lo, hi)
        quick_sort_hoare(A, lo, p)
        quick_sort_hoare(A, p + 1, hi)

Complexity and Properties

  • Time complexity: Best and average case O(n log n); worst case O(n^2) if partitions are highly unbalanced (e.g., poor pivot choices on already sorted data).
  • Space complexity: O(log n) additional space on average due to recursion depth; worst case O(n).
  • Stability: Not stable by default (equal elements may change relative order). Stable variants exist but are more complex.
  • In-place: Yes (for standard implementations), which reduces memory overhead and improves cache performance.

Pivot Selection Strategies

  • Last/first element: Simple but risky for already sorted or adversarial inputs.
  • Random pivot: Randomizes performance, making worst cases unlikely in practice.
  • Median-of-three: Choose the median of first, middle, and last elements to reduce the chance of poor partitions.

Handling Duplicates

When many elements are equal to the pivot, standard two-way partitioning can degrade. A three-way partition (Dutch National Flag) splits elements into less-than, equal-to, and greater-than partitions, improving performance with many duplicates.

Optimizations in Practice

  • Switch to a simpler sort for small partitions: Many implementations switch to a small-array sort (e.g., insertion sort) for subarrays below a threshold (like 10–20 elements) to reduce overhead.
  • Tail recursion elimination: Recurse into the smaller partition first and iterate on the larger one to cap recursion depth at O(log n).
  • Introspective sort (introsort): Start with Quick Sort, but detect deep recursion and fall back to Heap Sort to guarantee O(n log n) worst-case time.

When to Use Quick Sort

  • General-purpose in-memory sorting when stability is not required.
  • Datasets that fit in CPU cache benefit from its locality.
  • Scenarios where average speed and low constant factors matter.

Comparisons to Other Sorts

  • Merge Sort: Predictable O(n log n) even in worst case and stable, but needs O(n) extra space (unless using complex in-place variants).
  • Heap Sort: O(n log n) worst-case and in-place, but often slower in practice due to cache behavior.

Example Walkthrough

Sort [9, 3, 7, 1, 8, 2] with pivot = 2 (Lomuto):

  1. Partition around 2 → [1, 2, 7, 9, 8, 3], pivot index = 1
  2. Recurse left on [1] (already sorted) and right on [7, 9, 8, 3]
  3. Repeat until subarrays are size 0 or 1

Common Pitfalls

  • Consistently poor pivot selection (e.g., always first/last on sorted data) causing O(n^2) behavior.
  • Incorrect partition boundaries leading to infinite recursion or missed elements.
  • Stack overflow on worst-case recursion depth; mitigate with tail recursion elimination or iterative approach.

Applications

  • Order statistics: Quickselect for finding k-th smallest/largest element.
  • Top-k problems: Partial sorting by partitioning around pivots.
  • Parallel and distributed variants: Partitioning enables parallel subproblem processing.

Context from Referenced By

Context from Related Topics
Pop Quiz
Topic: quick_sort
Level: 1
True or False:

Standard Quick Sort implementations are not stable by default.

Topic: quick_sort
Level: 1
Multiple Choice:

Which partition scheme in Quick Sort typically performs fewer swaps and is often faster, especially with many equal keys?

Topic: quick_sort
Level: 1
Fill in the Blank:

Quick Sort has an average-case time complexity of _____.

Topic: quick_sort
Level: 2
True or False:

Quick Sort uses O(log n) additional space on average due to its recursion depth.

Topic: quick_sort
Level: 2
Multiple Choice:

Which hybrid sorting strategy begins with Quick Sort but switches to Heap Sort when recursion becomes too deep to guarantee O(n log n) worst-case time?

Topic: quick_sort
Level: 2
Fill in the Blank:

To cap Quick Sort's recursion depth at O(log n), implementations often use _____ by always recursing on the smaller partition and iterating on the larger one.

Topic: quick_sort
Level: 3
True or False:

A three-way partitioning strategy in Quick Sort reduces performance degradation when many elements are equal to the pivot.

Topic: quick_sort
Level: 3
Multiple Choice:

Which optimization is commonly applied in practical Quick Sort implementations when subarrays become very small (e.g., below 10–20 elements)?

Topic: quick_sort
Level: 3
Fill in the Blank:

Always picking the _____ element as the pivot in Quick Sort can cause O(n^2) time on already sorted input.

Topic: quick_sort
Level: 4
True or False:

Randomly selecting the pivot in Quick Sort reduces the likelihood of worst-case O(n^2) behavior on typical inputs.

Topic: quick_sort
Level: 4
Multiple Choice:

In Quick Sort using Hoare's partition scheme, the partition function returns an index p. Which pair of recursive ranges correctly continues the sort?

Topic: quick_sort
Level: 4
Fill in the Blank:

Quick Sort is widely used in practice due to excellent average performance and small _____ factors.

Topic: quick_sort
Level: 5
True or False:

Quick Sort is generally more cache-friendly than Heap Sort due to better locality of reference.

Topic: quick_sort
Level: 5
Multiple Choice:

In a standard in-place Quick Sort, what is the worst-case additional space complexity due to recursion depth?

Topic: quick_sort
Level: 5
Fill in the Blank:

Quick Sort is a classic example of the _____ paradigm.

Next Topic
depends_on
0.95

Partition Scheme
Quick Sort requires a partition scheme (e.g., Hoare or Lomuto) to split the array around a pivot; this step determines element arrangement and heavily influences performance and correctness.
used_by
0.93

Intro Sort
Introsort begins with quicksort for its fast average-case performance, then switches to heapsort (and often insertion sort for tiny partitions) when recursion depth exceeds a limit to guarantee O(n log n) worst-case time.
depends_on
0.92

Pivot Selection
Choosing an effective pivot (e.g., randomized or median-of-three) is crucial to balance partitions, preserve average O(n log n) behavior, and mitigate worst-case O(n^2).
related_to
0.9

Quick Select
Quick Select adapts Quick Sort’s partitioning to find the k-th smallest element without fully sorting, sharing pivot choice, partition schemes, and similar average-case behavior.
used_by
0.9

Introsort
Introsort uses Quick Sort as its primary phase, switching to Heap Sort when recursion depth grows too large and often to Insertion Sort for small partitions, avoiding Quick Sort's O(n^2) worst case while keeping its average performance.
extends
0.9

Introsort
Introsort begins with Quick Sort for speed and switches to Heap Sort when recursion depth exceeds a threshold, ensuring O(n log n) worst-case performance.
used_by
0.86

Introsort
Introsort uses Quick Sort as its primary phase and switches to Heap Sort when recursion depth exceeds a threshold, avoiding Quick Sort's O(n^2) worst case.
calls
0.78

Three Way Partitioning
Three-way partitioning divides the array into < pivot, = pivot, and > pivot regions, serving as the partition step in Quick Sort variants to handle many duplicate keys efficiently.