Learn
Lesson · Sorting and Selection · Not comparing at all

Bucket Sort and Average-Case Claims

Scatter n keys into b equal-width buckets, insertion-sort each bucket, and concatenate. If the keys are uniform over the range, the expected work inside the buckets is n(n/b − 1)/2, which is linear when b is about n. That expectation is over the input distribution, not over anything the algorithm does, so it stops being true exactly when the keys stop being uniform — and the algorithm cannot tell.

scatter into b equal-width buckets, insertion-sort each, concatenate E[work inside the buckets] = n(n/b − 1)/2 IF the keys are uniform 48 keys, 12 buckets: expected 72, measured 90 on a uniform draw the same 48 keys clustered in a twentieth of the range: 592 worst possible for 48 keys: n(n − 1)/2 = 1128
The expectation, its hypothesis, and what happens when the hypothesis fails

Core ideas

What this lesson establishes

The hard idea is a distinction, and it is the reason this lesson sits four after randomised quicksort rather than next to the other linear-time sorts.

1

This expectation is over the input, not over the algorithm

Randomised quicksort's 2(n+1)Hₙ − 4n averages over the pivots the algorithm draws, so it holds for every array. Bucket sort's linear bound averages over a distribution the input is assumed to follow, and the algorithm makes no random choices at all: run it twice on the same keys and it does exactly the same thing. An assumption about the data is a promise somebody else has to keep.

2

The work is all inside the buckets

Scattering is one pass and concatenating is another, so the interesting term is the insertion sorts. A bucket holding m keys costs up to m(m − 1)/2 comparisons, and summing that over buckets with n/b keys each gives n(n/b − 1)/2 — zero when every bucket holds one key, and n(n − 1)/2 when one bucket holds all of them. The whole range of behaviour is in how the keys divide.

3

The bound fails exactly when the distribution does

Nothing about the algorithm changes when you change the distribution; the same code runs. At 48 keys in 12 buckets a uniform draw measures 90 comparisons, keys clustered in a twentieth of the range measure 592, and keys confined to one bucket measure 582. Double n on the clustered family and the count goes from 140 at 24 keys to 592 at 48 to 2282 at 96: roughly four times the work for twice the keys, which is what a quadratic cost looks like when it is measured.

The material

A linear expectation, and the hypothesis it is standing on

Where the expected work comes from, what it assumes, and what the same algorithm costs when the assumption is false.

Definition · Bucket sort

Bucket sort over a key range [0, U) with b buckets: place each key x into bucket ⌊bx/U⌋, sort each bucket with insertion sort, and concatenate the buckets in order. The buckets are equal in width; nothing makes them equal in occupancy.

The scatter is Θ(n) and the concatenation is Θ(n + b). Everything else is the insertion sorts, and their cost depends on the bucket sizes, which depend on the keys. So the analysis is not about the algorithm at all: it is about a random variable determined by where the keys fall.

if every bucket holds n/b keys, insertion sort inside one costs (n/b)(n/b − 1)/2 at worst summed over b buckets: b · (n/b)(n/b − 1)/2 = n(n/b − 1)/2 n = 48, b = 12: 48 · (4 − 1)/2 = 72 exactly n = 96, b = 12: 96 · (8 − 1)/2 = 336 n = 48, b = 48: 48 · (1 − 1)/2 = 0

With b = n the expected inner work is zero, which is the sense in which bucket sort is called linear: the remaining cost is the scatter and the concatenation. The lab evaluates the expression as an exact rational, because the point of printing it beside a measurement is that the two are different kinds of number and can be subtracted.

Example · Forty-eight keys, three distributions, one algorithm

Twelve buckets throughout. A uniform draw fills them 4 4 9 2 3 0 3 4 3 1 8 7 and costs 90 comparisons against an expectation of 72. Keys clustered in a twentieth of the range put all 48 into one bucket and cost 592. Keys confined to the first bucket cost 582. All three outputs are sorted; only the cost moved, and the code did not.

The gap between 72 and 90 on the uniform draw is worth a sentence of its own, because it is the honest half of the lesson. 72 is an expectation over the distribution; 90 is one draw from it. The bucket sizes above are visibly uneven — one bucket empty, one holding nine — and that unevenness is what a uniform draw looks like at n = 48. A measurement above the expectation is not a refutation of it.

Two expectations, side by side

Put the two claims of this course in the same sentence and the difference is unmissable. Randomised quicksort: for every array, the average over the algorithm's pivots is 2(n+1)Hₙ − 4n. Bucket sort: for keys drawn uniformly, the average over the draw is n(n/b − 1)/2. The first quantifies over inputs and averages over coins the algorithm controls; the second averages over inputs and controls nothing.

That is why one of them survives a hostile input and the other does not. An adversary who picks the array cannot move randomised quicksort's expectation, because the expectation never mentioned the array. An adversary who picks the keys moves bucket sort's cost to Θ(n²) by putting them all in one bucket, and the lab ships exactly that input.

None of which makes bucket sort a bad algorithm. It makes its bound a conditional one, and the condition is checkable: where do the keys come from, and is the range they are spread over the range the buckets divide? Hash values, uniformly generated identifiers and quantised sensor readings often satisfy it. Prices, word lengths and timestamps of human activity usually do not.

One last discipline. The measured 582 on the one-bucket input is not the worst case; n(n − 1)/2 = 1128 is, and insertion sort only reaches it on a reversed bucket. The measured column is one input's cost and the proved column is about all of them, and this page keeps them apart on purpose.

Interactive

Bucket sort is linear when the keys agree to be uniform

Change the distribution and nothing about the algorithm changes but its cost

An average-case bound is a claim about the inputper-bucket insertion sort work, under a distribution you choose
bucket occupancycomparisons inside a bucketthe work if the keys were uniform

Method

Reading an average-case claim

Every average-case bound has a hypothesis. Find it before you find the bound.

1

Say what the expectation is over

Over the algorithm's own random choices, or over a distribution the input is assumed to follow? Write the sentence out in full. If the answer is the second, the bound is a conditional statement and the condition belongs in every quotation of it.

2

Compute the expected work before measuring anything

n(n/b − 1)/2 at your n and b. At 48 keys over 12 buckets it is exactly 72. This is the number the measurement will be compared against, and having it first stops the measurement from becoming the claim.

3

Measure a draw, and expect it to differ

90 against 72 on the uniform draw. A single draw is a sample of the distribution the expectation is over, so it moves when the seed moves. Watch it move.

4

Now break the hypothesis on purpose

Switch to the clustered keys and read the count: 592 for the same 48 keys through the same code. Then change n and check the growth. Roughly four times the work for twice the keys is quadratic behaviour on this family — measured, not proved.

5

Report the bound with its condition attached

“Linear if the keys are uniform over the bucketed range, quadratic in the worst case” is the whole claim. Θ(n) on its own is the misconception, and it is the one the lab's distribution control exists to break.

Which expectation, over what

Score 0 / 0

Forty-eight keys through twelve buckets, three ways

The bucket count, the key count and the code are identical in all three rows. Only where the keys fall is different, and the expectation in the second column is the same number throughout because it is computed from n and b alone.

expected inner work, if uniform: n(n/b − 1)/2 = 48 · 3/2 = 72 (exact) distribution bucket sizes measured per key uniform over the range 4 4 9 2 3 0 3 4 3 1 8 7 90 1.88 clustered in a twentieth 0 48 0 0 0 0 0 0 0 0 0 0 592 12.33 all inside the first bucket 48 0 0 0 0 0 0 0 0 0 0 0 582 12.13 growth of the clustered family, twelve buckets throughout n = 24 140 n = 48 592 4.2 × the work for 2 × the keys n = 96 2282 3.9 × worst possible at n = 48: n(n − 1)/2 = 1128 all three outputs were checked against the sorted array: all three sorted

The middle column is the only thing that changed, and it is not part of the algorithm. That is the entire content of “an average-case bound is a claim about the input”, and it is why the row for the clustered keys is the same code costing six and a half times as much.

Two figures are deliberately not equal to anything. 90 is not 72, because one draw is not an expectation. And 592 is not 1128, because the worst case needs the one full bucket to be in reverse order as well as full — the measured column is this input and the proved column is all of them.

For a faded rehearsal, keep the clustered keys and raise the bucket count from 12 to 32. The supplied first move is the prediction: the buckets are equal-width, and the keys occupy a twentieth of the range, so widening the bucket count divides that twentieth among at most two buckets. Say whether the cost falls by much, then check — and then say what bucket count would actually fix this input, and whether you could have known it without seeing the keys.

Common mistakes

1
Quoting O(n) without the hypothesisThe bound is conditional and the condition is about where the keys come from. Repeating the conclusion without it is how an algorithm gets chosen for data it was never analysed on, and the failure is silent: the output is still correct, just six times dearer, and it gets dearer faster as n grows.
2
Confusing an average over inputs with an average over coin flipsRandomised quicksort's expectation holds for each input separately because the randomness belongs to the algorithm. Bucket sort's holds for a distribution of inputs and says nothing about the input you have. Both sentences begin “expected”, and only one of them is a promise the algorithm can keep on its own.
3
Reading a measured quadratic count as the worst case582 comparisons on 48 keys in one bucket is a measurement; the worst case is n(n − 1)/2 = 1128, reached only when that bucket is also in reverse order. This course prints the measured and the proved figure side by side for exactly this reason, and a count on one input never becomes a bound by being large.

Check your understanding

✓
Finish when you can state an average-case bound with its hypothesis and then break it.

You should be able to derive n(n/b − 1)/2, evaluate it exactly at a given n and b, say what the expectation is over, produce an input that makes the algorithm quadratic, and explain why randomised quicksort's expectation is a different kind of claim.

Note: That closes the sorts. The next two lessons ask for less than a sorted array — a single order statistic — and find that less work is needed for it. “Quickselect” recurses into one side only, and the recurrence loses a term, which turns out to be the whole difference between n log n and linear.

Kept in this browser only, for you. Nothing is sent anywhere and nothing checks it. Carry it to another device.

Feedback and recommendations

Something to change about this lesson? Write it down, tick it off when it is handled, and export the list when you want to act on it. Kept in this browser only: nothing is sent anywhere, and nobody is notified.

No recommendations yet for this lesson.