Hashing: functions and collisions
Hash tables as a dictionary with expected constant time: direct addressing, hash functions and the table size, the division and multiplication methods and why the choice of m matters, string hashing, universal hashing, the load factor, why collisions are unavoidable and appear far sooner than expected (the birthday paradox).
Why it exists
Searching an unsorted array takes and searching a sorted array takes , but an array indexed by the key itself takes : look at position . Hashing keeps that speed for keys that are not small integers (names, long numbers, strings) by turning the key into an array index with a hash function. The expected cost of search, insert and delete is then constant, which is why hash tables are the default dictionary of most programming languages. The price: two keys can get the same index (a collision), and the order of the keys is lost.
Prerequisites
You need arrays with constant-time access by index (arrays).
Precise definitions
Dictionary. A set of keys (with attached data) supporting insert, search and delete.
Universe and table. The keys come from a universe that is usually huge ( = all 32-bit numbers, all strings). The table is an array of slots (buckets), with .
Direct-address table. If is small, store the record of key in . All three operations take time, but the space is , hopeless when and only a few thousand keys are present.
Hash function. A function . The key is stored in (or searched at) slot . It must be deterministic (the same key always gives the same value) and fast.
Collision. Two different keys with . Since , collisions cannot be avoided for all inputs (pigeonhole): among any distinct keys at least two collide.
Load factor. for keys stored in slots. It is the average number of keys per slot.
Simple uniform hashing assumption (SUHA). Each key is equally likely to hash to any of the slots, independently of the other keys. Almost all average-case results on hashing are proved under this assumption; it is what a good hash function tries to imitate.
How it works
Collisions come early
By pigeonhole a collision is certain after keys. But it is likely much sooner. Hash keys independently and uniformly into slots. The probability that no two collide is because the -th key must avoid the slots already used. The expected number of colliding pairs is (each of the pairs collides with probability ). For slots a collision becomes more likely than not with only keys (the birthday paradox; in general about keys), when the table is only full.
Collisions are likely much sooner than expected: start
Computed by a script, not typed| number of keys | P(some collision) | P(no collision) | expected colliding pairs C(k,2)/365 |
|---|---|---|---|
| k = 5 | |||
| k = 10 | |||
| k = 15 | |||
| k = 20 | |||
| k = 23 | |||
| k = 30 | |||
| k = 40 | |||
| k = 50 | |||
| k = 60 | |||
| k = 70 |
Step 0
k keys are hashed independently and uniformly into 365 slots. The exact probabilities are computed with fractions: with only 23 keys a collision is already more likely than not.
Hash functions
A good hash function spreads the keys of the application evenly, whatever pattern they have. The standard ones for integer keys:
Division method. . Fast and simple, but the quality depends on . If shares a factor with a pattern in the keys, whole buckets stay empty and others overflow. Advice: choose a prime not close to a power of (or ). Never take if the keys' low bits are not random, since only looks at the last bits.
Multiplication method. for a constant (Knuth suggests ): multiply the key by , keep the fractional part, multiply by and take the integer part. The value of is not critical, so can be a power of two, which makes the computation a multiplication and a shift on machine words. For and : , fractional part , so .
Other ideas. Mid-square: square the key and take the middle digits. Folding: cut the key into pieces and add them. Strings: treat the characters as digits of a number in some base and reduce by Horner's rule, , so that all characters, in order, influence the result.
Universal hashing. Any single fixed function has a bad set of keys (an adversary can choose keys that all collide). Choosing the function at random from a family at the start defeats this. For a prime , the family with random and has the property that for any two different keys the probability (over the choice of ) that they collide is at most (checked exhaustively on small cases), so the expected cost is as for SUHA whatever the keys are.
What the choice of does. The program hashes the twenty keys (multiples of , a typical pattern) with several and counts how many buckets are used and how large the largest bucket is.
#include <stdio.h>
#include <math.h>
#define N 20
/* the keys are 10, 20, ..., 200: a pattern such as real keys often have (multiples of a round number) */
static void report(const char *name, int m, int (*h)(int, int)) {
int load[64] = {0}, used = 0, max = 0;
for (int i = 1; i <= N; i++) load[h(10 * i, m)]++;
for (int b = 0; b < m; b++) {
if (load[b] > 0) used++;
if (load[b] > max) max = load[b];
}
printf("%-15s m = %2d buckets used = %2d largest bucket = %2d\n", name, m, used, max);
}
static int division(int key, int m) { return key % m; }
static int multiplication(int key, int m) {
double a = 0.6180339887498949, x = key * a; /* A = (sqrt(5) - 1) / 2 */
return (int)(m * (x - floor(x)));
}
int main(void) {
report("division", 10, division);
report("division", 11, division);
report("division", 16, division);
report("division", 13, division);
report("multiplication", 16, multiplication);
printf("\nprobability that k keys, hashed uniformly into 365 slots, have a collision:\n");
int ks[4] = {10, 23, 30, 50};
for (int t = 0; t < 4; t++) {
double none = 1.0;
for (int i = 0; i < ks[t]; i++) none *= 1.0 - i / 365.0;
printf("k = %2d %.4f\n", ks[t], 1.0 - none);
}
return 0;
}division m = 10 buckets used = 1 largest bucket = 20
division m = 11 buckets used = 11 largest bucket = 2
division m = 16 buckets used = 8 largest bucket = 3
division m = 13 buckets used = 13 largest bucket = 2
multiplication m = 16 buckets used = 13 largest bucket = 2
probability that k keys, hashed uniformly into 365 slots, have a collision:
k = 10 0.1169
k = 23 0.5073
k = 30 0.7063
k = 50 0.9704Spreading the keys 10, 20, ..., 200 over a table: start
Computed by a script, not typed| hash function | buckets used (of m) | empty buckets | largest bucket | average load 20 / m |
|---|---|---|---|---|
| division, m = 10 | ||||
| division, m = 11 | ||||
| division, m = 16 | ||||
| division, m = 13 | ||||
| multiplication, m = 16 |
Step 0
Twenty keys that are multiples of 10 are hashed by key mod m for four table sizes and by the multiplication method. A good function uses every bucket and keeps the largest one small.
With every key lands in bucket : the table degenerates into one list. With only even buckets are used (the factor of the keys is shared). Primes and spread the keys well. The multiplication method copes even with .
Resolving collisions
Because collisions happen, a hash table needs a rule for keys that share a slot: chaining (each slot holds a list of keys) or open addressing (a colliding key is put into another slot of the table, found by a probe sequence). They are the subject of the next page; the expected cost as a function of the load factor is in load factor and expected probes.
What a hash table cannot do well: keep keys in sorted order, find the next larger key, or report all keys in a range. A search tree does those in ; a hash table needs time.
Worked examples
EX 1Hash five keys with the division method
Easy, (the last digit): , , , , . The keys and collide in bucket . With the buckets would be , , , , : no collision this time; whether there is one depends on both the keys and .
EX 2How many keys until a collision is certain, and likely?
EasyIn a table with slots, keys force a collision (pigeonhole): the maximum number of keys that can be stored without any collision is . A collision becomes more likely than not after about keys. The expected number of colliding pairs for random keys is : for and it is .
EX 3Bad table size
MediumA system hashes record numbers that are always multiples of with . Only the slots and can ever be used, whatever the number of records: the table behaves as if it had slots. With a prime such as the multiples of are spread over all slots (since , the residues of cycle through all of them).
EX 4The multiplication method by hand
Medium, . For : , fractional part , . For the result is (above). Two keys that are close together ( and ) go to far-apart slots, because multiplying by scatters them: this is the desired behaviour, unlike the division method with a power-of-two modulus, where neighbouring keys go to neighbouring slots.
EX 5Counting collisions
GATE level(a) keys are hashed into slots with ; the keys are and . Every bucket receives exactly keys (the last digit repeats every keys): no bucket is empty but every bucket has a chain of . (b) What is the smallest number of keys that guarantees a collision in a table of slots? . (c) What is the load factor of a table with keys in slots? , possible for chaining (average chain ) but impossible for open addressing. (d) A hash function sends every key to slot . It is a legal function and the table works, but every operation costs : correctness does not depend on the quality of , only speed does.
Cheat box
Cheat box
- Direct addressing: but space . Hash table: slots, , load factor .
- Collision: , ; unavoidable ( keys force one) and likely early (birthday: keys, for ). Expected colliding pairs .
- Division: , a prime not near a power of . Multiplication: , , any .
- SUHA: each key equally likely in each slot, independently. Universal hashing: random from a family, collision probability for any two keys.
- Correctness never depends on ; only the running time does. A hash table does not keep order.
Traps and GATE patterns
Connections
Builds on
Unlocks
Across subjects
Searching by hashing is compared with binary search (needs order) and with binary search trees (BST). The two ways to handle collisions are in chaining and open addressing and their costs in load factor and expected probes. Using the key as an array index is also the idea behind counting sort.
PYQs
3 previous year questions from your book. I re-solved each one myself (2 by running or simulating, 1 by reasoning only); the book's key is shown next to my answer. All PYQs
An algorithm has to store several keys generated by an adversary in a hash table. The adversary is malicious who tries to maximize the number of two simple uniform hash functions h1 and h2. Further suppose our hashing scheme uses h1 for the odd keys and h2 for the even keys. What is the expected number of keys in a slot?
- (a)m/n
- (b)n/m
- (c)2n/m
- (d)n/2m
Consider a dynamic hashing approach for 4-bit integer keys: 1. There is a main hash table of size 4. 2. The 2 least significant bits of a key is used to index into the main hash table. 3. Initially, the main hash table entries are empty. 4. Thereafter, when more keys are hashed into it, to resolve collisions, the set of all keys corresponding to a main hash table. entry is organized as a binary tree that grows on demand. 5. First, the 3rd least significant bit is used to divide the keys into left and right subtrees. 6. To resolve more collisions, each node of the binary tree is further sub-divided into left and right subtrees based on the 4th least significant bit. DATA STRUCTURE 7. A split is done only if it is needed, i.e., only when there is a collision. Consider the following state of the hash table. Which of the following sequences of key insertions can cause the above state of the hash table (assume the keys are in decimal notation)?
- (a)5,9,4,13,10,7
- (b)9,5,10,6,7,1
- (c)10,9,6,7,5,13
- (d)9, 5,13,6,10,14
Which one of the following hash functions on integers will distribute keys most uniformly over 10 buckets numbered 0 to 9 for i ranging from 0 to 2020?
- (a)h(i)= i2 mod 10
- (b)h(i)= i3 mod 10
- (c)h(i)=(11*i2) mod 10
- (d)h(i)=(12*i2) mod 10
Self-check
Question 1
How many keys must be inserted into a table of slots to guarantee at least one collision?
Show answerHide
(pigeonhole).
Question 2
Why is a poor function for keys that are multiples of ?
Show answerHide
takes only the values for such keys: at most of the slots are used.
Question 3
State the simple uniform hashing assumption.
Show answerHide
Each key is equally likely to hash to each of the slots, independently of where the other keys hash.
Question 4
Can a hash table keep its keys sorted?
Show answerHide
No: hashing destroys the order of the keys. Finding the minimum or the next larger key costs .
Revision card
One-screen revision
- ; load factor ; collision unavoidable ( keys).
- Birthday: collision likely after keys; expected colliding pairs .
- Division ( prime); multiplication ; strings by Horner; universal hashing.
- Expected under SUHA with constant ; worst case ; no order.
References
- ·Cormen, Leiserson, Rivest, Stein, Introduction to Algorithms (3rd edition), Chapter 11 Hash Tables (11.1 direct-address tables, 11.2 hash tables, 11.3 hash functions)
- ·Sedgewick and Wayne, Algorithms (4th edition), Section 3.4 Hash Tables
- ·Knuth, The Art of Computer Programming, Volume 3, Section 6.4 Hashing
Verification
The spread of the keys over buckets was measured by the C program on this page and recomputed in Python. The birthday probabilities are exact (Fractions) and the program's floating-point output matches them to four decimals; 23 keys is the smallest number with a collision probability above one half. The expected number of colliding pairs C(n,2)/m and the collision probability were verified by enumerating every one of the m^n assignments for small m and n. The statement that the family ((ak + b) mod p) mod m collides with probability at most 1/m was checked exhaustively for eight pairs (p, m). The multiplication and string examples were recomputed. The advice on the choice of m (a prime not close to a power of two) is the standard textbook advice and is illustrated, not proved. Textbook chapter references are from memory. SECOND PASS (2026-11-02, done by the assistant, not a human check): every Self-check question was solved before the printed answer was read and all agreed; the definitions, worked examples, cheat box and traps were read claim by claim and the numbers re-derived by hand or by a small script (loop counts, recurrences, merge and quicksort counts and averages, hash probes and load-factor formulas, DP tables, MST and shortest-path runs, Floyd matrices); long C programs were not re-read line by line (they are compiled and compared by npm run verify:c, and their printed outputs were checked against the prose); tables and animations are machine output and were read, not re-run; No other defect found. Status raised to self-checked; verified needs a textbook or human check.
last verified: never
My notes (saved in this browser)