3.3.1 · D5Hashing
Question bank — Hash function — properties - deterministic, uniform, fast
This bank targets the misconceptions around the three properties — never the arithmetic (that lives in the computation drills). Focus on why the property is what it is and where it quietly breaks.

True or false — justify
A hash function that spreads keys perfectly evenly but changes its answer between runs is still useful.
False — evenness (uniformity) is worthless without determinism; if
insert("cat") and lookup("cat") compute different buckets you can never retrieve the key.If two keys collide, the hash function is broken.
False — collisions are unavoidable by the Pigeonhole Principle since the universe is far larger than ; a good hash makes them rare and evenly spread, it does not eliminate them.
A cryptographically secure hash (like SHA-256) is always the best choice for a hash table.
False — it is deterministic and uniform but slow; hashing's whole point is a tiny constant-time cost, so Cryptographic Hash Functions usually violate the "fast" property for this use.
Simple Uniform Hashing means every bucket ends up with exactly the same number of keys.
False — SUH is about probability ( for each bucket ), not a guarantee; it makes the expected pile height, but real counts fluctuate around it (see Figure 4).
Using is fine because it always lands in range.
False — a power-of-two modulus keeps only the low-order bits of , so keys sharing those bits cluster; a prime mixes all bits (see Figure 2). Grounded in Modular Arithmetic.
Determinism forbids a hash function from ever using a random seed.
False — a seed fixed once per table is fine and still deterministic; only a fresh random value per call breaks determinism.
Making a hash function faster always costs you uniformity.
False — they are separate goals; a well-designed polynomial string hash is both fast (cost grows with key length , not with ) and well-distributed. Speed and spread are not a strict trade-off.
If the load factor is well below 1, collisions cannot happen.
False — only means fewer keys than buckets on average; two keys can still map to the same bucket , so piles of height 2+ still occur.
A hash function is uniform if it uses all buckets at least once.
False — using every bucket says nothing about balance; 90% of keys could still pile into one bucket while the others hold one each.
Spot the error
"I'll call random() inside h() to spread keys better."
The error is per-call randomness — it destroys determinism, so the same key hashes differently each time and
lookup fails. Fix: fix any randomness as a per-table seed."Phone numbers hash fine with since 1000 is big."
The error is a power-of-ten modulus: it looks only at the last 3 digits and ignores the rest of . In many real numbering plans those trailing digits are handed out sequentially within an exchange or block, so nearby subscribers share ranges — mild but real clustering. A prime folds in all digits, which is the robust default whatever the data looks like.
"I hash strings by summing their ASCII codes — simple and fast."
The error is losing order information:
"abc", "cab", "bca" share the same sum and collide. Positional weights (polynomial hash, a small prime) distinguish character order."To keep search I never resize the table, I just add more keys."
The error is a growing : as climbs with fixed, the piles lengthen toward search. Fix is Load Factor and Rehashing — grow and rehash once crosses a threshold (see the "Why 0.75" question).
"My hash returns a value in but I compute the mod only at the very end of the string loop."
Not always an error mathematically, but the intermediate sum can overflow machine range for long strings; take mod at every Horner step to stay in range and keep the cost proportional to key length (see the Horner "why" question and Figure 5).
"Since collisions are inevitable, the choice of hash function doesn't really matter."
The error is treating all hashes as equal: a bad one dumps keys into few buckets (tall piles), a uniform one keeps expected pile height at . The distribution is exactly what matters. See Collision Resolution — Separate Chaining.
Why questions
Why is "fast" really "uniform in disguise's partner", i.e. why does uniformity protect speed?
Because search cost is and uniformity guarantees is the average pile height; without it, some buckets grow to and destroy the speed guarantee.
Why must the same seed give the same output for determinism to hold?
Determinism is defined given the fixed seed; retrieval recomputes with that same seed, so as long as it never changes between insert and lookup, the bucket is reproducible.
Why does a prime table size mix all the bits of a key?
Look at Figure 2. With , computing literally keeps the last bits and throws the rest away — two keys agreeing in those bits always collide, no matter how their high bits differ. A prime has no factor in common with the place-values , so each successive bit's contribution wraps around the bucket range by a different offset instead of vanishing. That coupling forces the remainder to depend on the whole key, not a fixed tail. Grounded in Modular Arithmetic.
Why is the resize threshold traditionally around and not, say, ?
With separate chaining, expected work is , so cost rises linearly with — waiting longer just means longer piles. With open addressing the cost is far more brutal: the expected probes for an unsuccessful search behave like . Plug in probes; probes; probes. The curve knees upward sharply near , so is a pragmatic point before the blow-up while still using memory reasonably. Figure 3 plots this. See Collision Resolution — Open Addressing and Load Factor and Rehashing.
Why is written with the "" instead of just ?
The is the always-present cost of computing the hash and reaching the bucket; the is the pile walk. When the cost is still 1, not 0.
Why does Horner's method let a string hash stay in machine range, so you never see the full ?
Follow Figure 5. Horner rewrites as — one multiply-add per character. Take a two-step toy with , on codes : start at ; step 1 gives ; step 2 gives . The running value never climbs past about , because the mod at every step chops it back into range before the next multiply — so the giant number is never actually formed.
Why does hashing cost grow with and not with ?
A string hash touches each of the characters exactly once (one multiply-add per character), so its work is ; it never looks at the other keys already in the table, so does not enter — which is exactly what the "fast" property demands.
Why do we accept collisions instead of designing a perfect one-to-one hash?
For an arbitrary huge universe , no fixed-size table can be collision-free (pigeonhole); a perfect hash needs the key set known in advance, which general Hash Table use does not have.
Edge cases
What is the expected pile height when (empty table)?
, so expected pile height is 0 and search cost is just the hash computation — the degenerate but consistent case.
What happens to the load factor and search cost when ?
, so expected pile height is 1; search stays on average with chaining, which is why is a sweet spot before rehashing.
Is a constant hash for all keys deterministic? Is it useful?
It is perfectly deterministic (same key → bucket 0 always) but maximally non-uniform — every key piles into bucket 0, degrading search to . Determinism alone is not enough.
What does hashing an empty string "" produce under the polynomial method?
The loop never runs (there are no , ), so the hash stays at its initial value (then ) — a valid, deterministic bucket, not an error.
If two identical keys are inserted, do they collide?
They are the same key , so by determinism they map to the same bucket — but this is intended duplicate handling, not a "collision" in the distinct-keys sense.
With (single bucket), what happens to uniformity and search?
, trivially "uniform" over one bucket, but so every operation degenerates to a linear scan — the boundary where a table becomes a list.
Connections
- Parent topic — the three properties in full.
- Pigeonhole Principle — why collisions are inevitable.
- Load Factor and Rehashing — the threshold behind the edge cases.
- Collision Resolution — Separate Chaining · Collision Resolution — Open Addressing — what happens after a collision.
- Cryptographic Hash Functions — deterministic and uniform but too slow for table use.