Worked examples — Bucket sort — uniform distributions
This page drills the parent topic through every case class bucket sort can throw at you. We start by mapping the whole terrain, then walk one fully-worked example per cell.
The scenario matrix
Bucket sort has a small number of "shapes" the input can take. Every shape stresses a different part of the algorithm. Here is the full list — every later example is tagged with the cell it covers.
| # | Cell class | What it stresses | Example |
|---|---|---|---|
| A | Typical uniform input in | the normal happy path, | Ex 1 |
| B | Boundary value or | the out-of-range index bug | Ex 2 |
| C | Zero / empty buckets | reading empty slots, degenerate | Ex 3 |
| D | Clumped / skewed input (worst case) | all-in-one-bucket, | Ex 4 |
| E | Rescaled range | the normalize-first step | Ex 5 |
| F | Cost accounting via | the probability analysis, numbers | Ex 6 |
| G | Negative + fractional real-world values | mapping messy units to | Ex 7 |
| H | Exam twist — duplicates & stability | ties inside one bucket | Ex 8 |
| I | Limiting behaviour — and huge | degenerate small case + trend | Ex 9 |
Nine cells, nine examples. Let's cover them all.
Ex 1 — Cell A: the typical uniform run
Steps.
-
Compute each index . Why this step? The index formula turns a value into an address — the whole reason bucket sort skips comparisons.
- ; ; ;
- ; ; ;
-
Drop into buckets. Why this step? This is the "Scatter" S — grouping without ordering.
-
Sort each non-empty bucket (only have items; both already ascending). Why this step? Buckets are tiny, so insertion sort is essentially free.
-
Concatenate left to right, skipping empties:

Verify: landed in bucket 4 (forecast). Buckets 5 and 6 are empty — 2 empty buckets. Output is strictly increasing and is a permutation of the input. ✅
Ex 2 — Cell B: the boundary value
Steps.
-
Compute naive indices. , , . Why this step? To expose the failure at the closed endpoint.
-
Notice the crash. Valid indices are . Index is out of range —
buckets[3]throws. Why this step? This is exactly the third [!mistake] in the parent note, made concrete. -
Apply the clamp fix:
idx = min(int(n*x), n-1). Why this step? It folds the single boundary point back into the top bucket without disturbing any interior value. Now . -
Re-bucket & concatenate: .
Verify: Naive index for is 3, which is invalid (). Clamped index is 2. Sorted output [0.2, 0.5, 1.0] is correct. ✅
Ex 3 — Cell C: mostly-empty (degenerate sparse) input
Steps.
-
Indices: , . Why this step? Small inputs cluster into low buckets, leaving many empty — the sparse degenerate shape.
-
Buckets: . Why this step? Shows the concatenation loop must gracefully skip 4 empty lists.
-
Concatenate: . The empties contribute nothing.
Verify: 2 non-empty buckets (), 4 empty. Output [0.11, 0.19] sorted. ✅
Ex 4 — Cell D: the worst case (everything clumps)
Steps.
-
Indices: , , , , . Why this step? All values live in , which is the single range mapping to bucket 4.
-
All five land in : , every other bucket empty. Why this step? This is the definition of the worst case — one bucket holds all items.
-
Cost of sorting : insertion sort on items costs comparisons in the worst case. With bucket size , this is . Why this step? It shows the average-case proof collapses when the uniform assumption is violated.
-
Concatenate (only contributes): .

Verify: All 5 values in bucket 4; worst-case comparisons (insertion sort), so growth. Output [0.90, 0.91, 0.93, 0.95, 0.99] correct. ✅
Ex 5 — Cell E: rescaled range
Steps.
-
Normalize with , here , width . Why this step? Bucketing only knows ; we must squeeze the original units into it first, keeping slots equal-width in the real units (each bucket spans units).
-
Compute:
-
Buckets: — one each.
-
Concatenate: .
Verify: bucket 2. Sorted output [12, 25, 30, 47]. Bucket spans are 10 units each. ✅
Ex 6 — Cell F: the cost analysis in numbers
Steps.
-
Model. Each element lands in bucket with , independently, so . See Binomial distribution. Why this step? Uniform input ⇒ equal per-bucket chance ⇒ this exact distribution.
-
Mean: . Why this step? Confirms the design goal: one item per bucket on average.
-
Variance: . Why this step? The spread measures "clumping" — how far bucket loads wander from 1.
-
Second moment via : Why this step? This matches the parent's — the constant that makes the algorithm linear.
-
Total quadratic work: . Why this step? Total insertion-sort cost = linear, the punchline.
Verify: , , , and . ✅
Ex 7 — Cell G: real-world word problem (negative + fractional)
Steps.
-
Set range: , width , so each bucket spans °C. Why this step? Negative values are no obstacle — normalization handles the shift automatically.
-
Normalize & floor with :
-
Buckets: .
-
Concatenate: (°C).
Verify: bucket 1. Sorted [-8.0, -3.5, 4.5, 12.0, 19.5] °C. ✅
Ex 8 — Cell H: exam twist — duplicates & stability
Steps.
-
Indices on the key: (three times), . Why this step? Equal keys ⇒ equal indices ⇒ same bucket. Ties are inevitable here.
-
Bucket receives, in scatter order, . Why this step? The scatter loop appends in input order, preserving original sequence.
-
Sort stably. A stable sort on equal keys keeps the existing order: . Why this step? Stability of the whole algorithm hinges on the per-bucket sort being stable.
-
Concatenate: .
Recall When is bucket sort stable?
Only if each bucket's internal sort is stable and elements are appended in input order. Which per-bucket sort keeps ties in order? ::: A stable one (e.g. insertion sort or a stable merge).
Verify: All three records in bucket 1; tie order a,b,d preserved. Output tags in order: c,a,b,d. ✅
Ex 9 — Cell I: limiting behaviour ( and )
Steps.
-
(a) Degenerate . Index . The lone bucket . Why this step? The smallest legal input must still behave — one bucket, one item, zero swaps.
-
Sort & concatenate: a 1-element list is already sorted → output
[0.7]. Why this step? Confirms the algorithm is a no-op on trivial input (no crash, no infinite loop). -
(b) Limit of : as , , so . Why this step? Shows the per-bucket quadratic work is bounded above by 2 forever — it never grows with , which is why the total stays .
-
Bound sanity: for every , . Even the smallest gives . Why this step? Every case, from to , lives in — no scenario escapes linearity.
Verify: (a) index , output [0.7]. (b) ; at the value is ; bound holds. ✅
Connections
- Bucket sort — uniform distributions — the parent this page drills.
- Binomial distribution — powers Ex 6's .
- Insertion sort — the per-bucket sort in Ex 1, 4, 8.
- Counting sort — the "one bucket per key" limit relevant to Ex 8's duplicates.
- Radix sort — repeated normalized bucketing generalizing Ex 5, 7.
- Comparison sort lower bound — why the address trick (Ex 1) beats .
- Hashing — same value-as-address idea seen in every scatter step.