Back to DSA Guide Catalog

Algorithmhard

Quick Sort Complete Guide

Quick sort partitions around a pivot so smaller values move left and larger values move right.

It is often one of the fastest general-purpose sorts in practice due to cache-friendly partitioning.

Its worst case is O(n^2), so pivot strategy and randomization matter.

Typical Complexity Baseline

MetricValue
AverageO(n log n)
WorstO(n^2)
SpaceO(log n) recursion

Video Explainer

Prefer video learning? This explainer gives a quick visual walkthrough of the core idea before you dive into the detailed sections below.

Sorting Visualizer

Step through Quick Sort to see how the list changes over time.

Quick Sort
Quick SortStep 1 / 34

Start with unsorted values.

9
3
7
1
8
2
6
4
5

Core Concepts

Learn the core building blocks and terminology in one place before comparisons, so the mechanics are clear and duplicates are removed.

Pivot selection

What it is: Chosen value used to split array into two regions.

Why it matters: Pivot selection is a required building block for understanding how Quick Sort stays correct and performant on large inputs.

Partition procedure

What it is: Reorder elements around pivot boundary.

Why it matters: Partition procedure is a required building block for understanding how Quick Sort stays correct and performant on large inputs.

Recursive subproblems

What it is: Sort left and right partitions recursively.

Why it matters: Recursive subproblems is a required building block for understanding how Quick Sort stays correct and performant on large inputs.

Recursion depth control

What it is: Tail recursion/randomized pivot to limit worst-case behavior.

Why it matters: Recursion depth control is a required building block for understanding how Quick Sort stays correct and performant on large inputs.

In-place swaps

What it is: Partition done directly on original array.

Why it matters: In-place swaps is a required building block for understanding how Quick Sort stays correct and performant on large inputs.

Pivot

What it is: Reference element used for partitioning step.

Why it matters: Reference element used for partitioning step. In Quick Sort, this definition helps you reason about correctness and complexity when inputs scale.

Partition index

What it is: Final pivot location after partitioning.

Why it matters: Final pivot location after partitioning. In Quick Sort, this definition helps you reason about correctness and complexity when inputs scale.

Randomized quicksort

What it is: Random pivot choice to reduce adversarial patterns.

Why it matters: Random pivot choice to reduce adversarial patterns. In Quick Sort, this definition helps you reason about correctness and complexity when inputs scale.

Tail recursion

What it is: Optimization style to reduce stack growth.

Why it matters: Optimization style to reduce stack growth. In Quick Sort, this definition helps you reason about correctness and complexity when inputs scale.

Quickselect

What it is: Partition-based algorithm to find kth statistic without full sort.

Why it matters: Partition-based algorithm to find kth statistic without full sort. In Quick Sort, this definition helps you reason about correctness and complexity when inputs scale.

Putting It All Together

This walkthrough connects the core concepts of Quick Sort into one end-to-end execution flow.

Step 1

Pivot selection

Chosen value used to split array into two regions.

Before

Array

9371825
  • Choose pivot=5

After

Partitioned

312 | 5 | 978
  • Pivot fixed at final position

Transition

Partition values < pivot to left
Partition values > pivot to right

Why this step matters: Pivot selection is a required building block for understanding how Quick Sort stays correct and performant on large inputs.

Step 2

Partition procedure

Reorder elements around pivot boundary.

Before

Left partition

312
  • Right partition [9,7,8]

After

  • Subproblems independent
  • Each side shrinks recursively

Transition

Recurse on left partition
Recurse on right partition

Why this step matters: Partition procedure is a required building block for understanding how Quick Sort stays correct and performant on large inputs.

Step 3

Recursive subproblems

Sort left and right partitions recursively.

Before

Subarray

312
  • Choose pivot=2

After

Subarray becomes

123
  • Left side sorted

Transition

Partition around 2
Place 2 between smaller/larger values

Why this step matters: Recursive subproblems is a required building block for understanding how Quick Sort stays correct and performant on large inputs.

Step 4

Recursion depth control

Tail recursion/randomized pivot to limit worst-case behavior.

Before

  • Both partitions recursively sorted
  • Need final combined order

After

Sorted array

1235789
  • Average runtime O(n log n)

Transition

No merge step needed
Array sorted in-place via partitioning

Why this step matters: Recursion depth control is a required building block for understanding how Quick Sort stays correct and performant on large inputs.

How It Compares

vs Merge Sort

When to choose this: Choose quick sort for in-place average-case speed.

Tradeoff: Merge sort has better worst-case guarantee and stability.

vs Heap Sort

When to choose this: Choose quick sort for practical cache-local performance.

Tradeoff: Heap sort avoids O(n^2) worst case but can be slower in practice.

vs Bubble Sort

When to choose this: Choose quick sort for any real production sorting workload.

Tradeoff: Bubble is only useful for pedagogy or tiny lists.

Real-World Stories and Company Examples

Language runtimes

Many standard library sort implementations use quicksort-inspired partitioning hybrids (often introsort variants).

Takeaway: Quick sort ideas are still central in production-grade sort engines.

Search ranking systems

Ranking pipelines repeatedly order candidate sets where partition-style selection helps prune work.

Takeaway: Partitioning concepts help both full sorting and top-k retrieval.

Ad-tech bidding systems

Latency-sensitive auction logic benefits from fast in-memory ordering of medium-size candidate arrays.

Takeaway: Average-case speed and memory locality are decisive in low-latency loops.

Implementation Guide

Partition around pivot, then recursively sort left and right partitions.

Complexity: Average O(n log n), Worst O(n^2), Space O(log n) recursion average

Lomuto-partition quick sort

function quickSort(values: number[], leftIndex = 0, rightIndex = values.length - 1): number[] {
  if (leftIndex >= rightIndex) return values

  const pivotValue = values[rightIndex]
  let storeIndex = leftIndex
  for (let scanIndex = leftIndex; scanIndex < rightIndex; scanIndex += 1) {
    if (values[scanIndex] <= pivotValue) {
      ;[values[storeIndex], values[scanIndex]] = [values[scanIndex], values[storeIndex]]
      storeIndex += 1
    }
  }

  ;[values[storeIndex], values[rightIndex]] = [values[rightIndex], values[storeIndex]]
  quickSort(values, leftIndex, storeIndex - 1)
  quickSort(values, storeIndex + 1, rightIndex)
  return values
}

Common Problems and Failure Modes

  • Choosing first/last pivot on nearly sorted input causing O(n^2).
  • Incorrect partition boundaries leading to infinite recursion.
  • Ignoring recursion-depth limits on huge arrays.
  • Assuming quick sort is stable when it is usually not.
  • Not switching to insertion sort for tiny partitions in optimized implementations.

Tips and Tricks

  • Pivot strategy drives performance; randomized or median-style pivots reduce worst-case risk.
  • Partition correctness is everything; test with duplicates and nearly sorted input.
  • Quick sort is often fastest in practice but not stable by default.
  • Switch to insertion sort for tiny partitions in optimized implementations.

When to Use

Use these signals to decide if this data structure/algorithm is the right fit before implementation.

Real-system usage signals

  • Strong average-case performance with low constant factors.
  • In-place partitioning requires less extra memory than merge sort.
  • Related partition logic underpins quickselect for kth-element problems.

LeetCode-specific tips (including pattern-identification signals)

  • Identification signal: partition-around-pivot approach with strong average performance is acceptable.
  • Identification signal: in-place sorting with cache-friendly behavior is preferred and worst-case can be mitigated.
  • If prompt discusses pivot strategy or partitioning, quick-sort family is likely intended.
  • For Quick Sort questions, start by naming the core invariant before writing code.
  • Use the constraint section to set time/space target first, then pick the data structure/algorithm.
  • Solve one tiny example by hand and map each transition to your variables before implementing.
  • Run adversarial cases: empty input, duplicates, max-size input, and sorted/reverse patterns when relevant.
  • During interviews, explain why your approach is the right pattern for this prompt, not just why the code works.

LeetCode Progression (Easy to Hard)

Back to DSA Guide Catalog
#ProblemDifficultyTypical Complexity
1Sort an ArrayMediumO(n log n) average
2Kth Largest Element in an ArrayMediumO(n) avg quickselect
3Top K Frequent ElementsMediumO(n log k)
4Wiggle Sort IIMediumO(n log n)
5Largest NumberMediumO(n log n)
6Sort ColorsMediumO(n)
7K Closest Points to OriginMediumO(n log k)
8Median of Two Sorted ArraysHardO(log(min(m,n)))
9Count of Smaller Numbers After SelfHardO(n log n)
10Reverse PairsHardO(n log n)