Order Statistics · Interactive Visualizer
A
Ahmed Al-Absi
Algorithms · Canadian University Dubai · 2025
Array Builder
k = 4
1st 10th
🎲 Random
⚠ Worst Case
〰 Nearly Sorted
≡ All Same
↓ Reversed
Playback Speed
0.25×
Controls
Step 0 / 0 IDLE
Search Space Remaining
Statistics
0
Comparisons
0
Swaps
0
Partitions
0
Discarded
Legend
Pivot
Active Space
Comparing
Swapping
Found!
Discarded
i / j Pointers
Array Visualization — Quickselect Partitioning
Pseudocode
Step Explanation
Press Build Steps to start the visualization.
Step History (click row to jump)
#ActionArray StateCmpsSwaps
CLO-1: Asymptotic Complexity Analysis
Overview
Growth Chart
Worst Case Demo
O(n)
Best / Avg Case
O(n²)
Worst Case
O(1)
Space (in-place)

Why Expected O(n)?

Each partition reduces the problem size on average by half. Unlike sorting O(n log n), Quickselect only recurses into one partition. The recurrence T(n) = T(n/2) + O(n) solves to O(n) by the master theorem.

Why Worst Case O(n²)?

If the pivot is always the minimum or maximum element, partition reduces size by only 1. Recurrence becomes T(n) = T(n-1) + O(n) → O(n²). This happens with sorted input and a fixed first-element pivot.

Comparison with Sort-then-Access

Naively sorting takes O(n log n) just to pick one element. Quickselect is strictly faster on average — it doesn't need the array fully sorted, just partitioned around the target rank.

Quickselect (actual avg)
Worst Case O(n²)
Sort-then-access O(n log n)
Theoretical O(n)

⚠ Worst Case Trigger: Sorted Array + First-Element Pivot

With a deterministic first-element pivot, every partition on a sorted array reduces the problem by only 1 — causing O(n²). See how comparisons skyrocket vs the random case.

CLO-2 & CLO-3: Divide & Conquer Paradigm
D&C Structure
Recursion Tree
vs. Quicksort
vs. Binary Search

Divide & Conquer

Break into smaller subproblems, solve recursively, combine results. Examples: Mergesort, Quicksort, Binary Search.

Quickselect D&C

Divide: Partition around pivot. Conquer: Recurse on one side only (containing rank k). No combine step needed!

The Key Insight: ONE Side Only

After partitioning, the pivot lands at its final sorted position p. If k = p+1 → done. If k < p+1 → recurse LEFT. If k > p+1 → recurse RIGHT. The other half is discarded permanently.

What if We Used a Different Paradigm?

Greedy: No natural greedy choice for finding k-th smallest without sorting. Dynamic Programming: No overlapping subproblems; partitions are independent. D&C is the natural fit.

The recursion tree is a path, not a full tree. Only one branch is taken at each level — unlike Quicksort which recurses on both sides.

Quickselect

Recurses on ONE side. Discards the other. O(log n) average depth. Goal: find ONE element.

Quicksort

Recurses on BOTH sides. Must sort everything. O(n log n) average work. Goal: sort entire array.

📖 What is the Selection Problem?

Given an unsorted array of n numbers, find the element that would be at position k if the array were sorted. This is called the k-th order statistic.

NAIVE APPROACH — O(n log n) Unsorted Sort All Return A[k] ⚠ Sorts ENTIRE array just to find one element Wasted work: all other n-1 sorted positions unused QUICKSELECT — O(n) average Unsorted Partition Recurse 1 side ✓ Discards half the array each step Only searches the side that contains k
k = 1
Minimum element
k = n/2
Median element
k = n
Maximum element
⚙️ How Lomuto Partition Works (Step by Step)

Partition rearranges the array so that all elements smaller than pivot go left, and all elements larger than pivot go right. The pivot ends up at its final sorted position.

Example: Partition [7, 2, 5, 1, 8, 3] — Pivot = 3 (last element)
Step 0 Step 1 Step 2 Final 7 2 5 1 8 3 pivot i=-1 j=0 2 7 5 1 8 3 i=0 ↑ j=1 2<3 → swap! 2 1 5 7 8 3 i=1 ↑ 1<3 → swap! 2 1 3 5 7 8 ← smaller than 3 rank 3 ✓ larger than 3 →
Lomuto Partition Rules
1. Pivot = last element A[right]
2. i = left − 1 (boundary of "small" zone)
3. For j = left to right−1:
   • If A[j] ≤ pivot: i++, swap A[i] ↔ A[j]
4. Swap A[i+1] ↔ A[right] (place pivot)
5. Return i+1 (pivot's final index)
Pointer Meanings
pivot — reference value at A[right]
i — right boundary of "smaller" zone
j — current element being checked
green cells — confirmed smaller than pivot
orange cells — confirmed larger than pivot
🔀 QuickSelect Decision Logic

After every partition, QuickSelect compares k to the pivot's position and decides where to go next. This is what makes it O(n) — it only ever follows one path.

Partition Array Compare k vs pivot rank k < rank Recurse LEFT side k > rank Recurse RIGHT side k == rank 🎯 FOUND! Pivot is the answer right half discarded ✕ left half discarded ✕
🔍 Full Worked Example: Find 3rd Smallest in [7, 2, 5, 1, 8, 3]
1
Start: array = [7, 2, 5, 1, 8, 3], k=3. Pivot = last element = 3. Search space = [0..5].
2
Partition [0..5]: Walk j from 0→4. Elements smaller than 3: 2 (at j=1), 1 (at j=3). Swap them left. Then place pivot 3 at index 2.
Result: [2, 1, 3, 7, 5, 8] → pivot at index 2 = rank 3.
3
Compare: k=3, pivot rank=3. k == rank → DONE! Answer = 3.
4
Verify: Sorted = [1, 2, 3, 5, 7, 8]. The 3rd smallest is indeed 3 ✓
After partition — only ONE check needed, both halves never touched again [2, 1] all < pivot (discarded) 3 rank 3 = k ✓ [7, 5, 8] all > pivot (discarded)
📊 Time Complexity — Why O(n)?
AVERAGE CASE — Work per level (ideal: pivot always splits in half) Level 1: n comparisons (full array) Level 2: n/2 comparisons Level 3: n/4 n/8 Total = n + n/2 + n/4 + n/8 + … = n × (1 + ½ + ¼ + …) = n × 2 = O(n) ✓
O(n)
Average case
Random input
O(n²)
Worst case
Sorted input + last pivot
O(1)
Space
In-place, no extra array
⚡ Key Concepts & Common Mistakes

✓ Quickselect vs Quicksort

Quicksort recurses BOTH sides after partition → O(n log n). Quickselect recurses ONE side only → O(n) average. They use the exact same partition function — only the recursion strategy differs.

✓ k is 1-indexed Rank

k=1 means the smallest (minimum). k=n means the largest (maximum). After partition, the pivot at 0-indexed position p has rank p+1. So if k=3, you're looking for the pivot at index 2.

✗ Wrong k after right recursion

When recursing right (k > pivotPos+1), you must adjust k relative to the new subarray: new k = k − pivotPos − 1. Forgetting this gives the wrong element.

✗ Assuming sorted output

QuickSelect does NOT sort the array. Only the k-th element ends up at its correct position. All other elements are partially rearranged but not sorted.

✓ Real-World Uses

Finding the median in O(n) · Top-K results in databases · Percentile calculations (e.g. 90th percentile load time) · Order book algorithms in finance · Graphics: finding median-cut for color quantization.

✓ Median of Medians

An advanced variant that guarantees O(n) worst case by choosing a provably good pivot deterministically. It divides the array into groups of 5, finds medians of each group, then recursively finds the median of those medians. Higher constant factor than randomized QuickSelect but provably optimal.