Load factor and expected probes
The expected cost of hashing as a function of the load factor alpha = n/m: chaining (alpha for an unsuccessful and 1 + alpha/2 for a successful search), open addressing under uniform hashing (1/(1 - alpha) and (1/alpha) ln(1/(1 - alpha))), linear probing (the Knuth formulas with the squared denominator), the derivations, measured values, and the expected number of empty slots and colliding pairs.
Why it exists
"Hashing takes expected constant time" needs a precise statement: constant provided the table is not too full. The load factor is the one number that decides the cost, and GATE asks for it directly: the expected number of probes of a search in chaining, linear probing and double hashing as a function of . This page derives the formulas, checks them against measurements, and shows how quickly open addressing degrades as .
Prerequisites
You need the collision-resolution schemes (chaining and open addressing) and the idea of an expected value (sum of value times probability, and linearity of expectation).
Precise definitions
Load factor. , with keys in slots. For open addressing ; for chaining may exceed .
Model. Simple uniform hashing for chaining: every key is equally likely to hash into any slot, independently. Uniform hashing for open addressing: the probe sequence of every key is equally likely to be any of the permutations of the slots. (Double hashing approximates it well; linear probing does not, which is why it has its own formulas.)
Cost measure. The number of probes of a search: for chaining the number of list nodes examined, for open addressing the number of table slots examined (including the final empty slot in an unsuccessful search and the slot with the key in a successful one).
How it works
Chaining
Under simple uniform hashing the list of the slot reached by a key not in the table has nodes on average, and an unsuccessful search examines all of them: nodes (plus the constant work of computing ). A successful search ends at the sought key. Suppose the keys were inserted at the front of their lists. The -th inserted key is preceded in its list by exactly the keys inserted after it that hash to the same slot; each of the later keys does so with probability , so the expected number of nodes examined to find it is . Averaging over : So a successful search costs about , an unsuccessful one (or counting the access of the slot). Both are : constant if , which is why is chosen proportional to . These two formulas were confirmed by enumerating every assignment of keys to slots for small and . The worst case is (all keys in one list).
Open addressing with uniform hashing
Consider an unsuccessful search in a table with keys in slots. It makes more than probes exactly when the first slots of its (random) probe sequence are all occupied, which has probability The expected number of probes is the sum of the probabilities of "more than probes" for , so (Exactly it equals .) An insertion costs the same as an unsuccessful search, since it probes until the first empty slot. A successful search for a key repeats the probes made when the key was inserted. The key that was the -th to be inserted found keys already present and needed at most probes on average, so Values: at an unsuccessful search needs probes and a successful one ; at they need and ; at they need and . The cost explodes as the table fills, but only for unsuccessful searches and insertions.
Linear probing
Linear probing does not follow the uniform hashing model: its runs of occupied slots keep growing (primary clustering), so it is worse. The classical result of Knuth for large tables is At : and probes. At : and . At : and . Compare with for uniform hashing at : the square in the denominator is the price of clustering.
Measured
The C program fills tables of slots with random keys up to a given load factor and averages the probes of every successful search and of unsuccessful searches, over tables for each setting, for chaining, linear probing and double hashing (with ).
#include <stdio.h>
#include <stdlib.h>
#define M 10007 /* a prime number of slots */
#define TRIALS 5
#define MISSES 20000
static unsigned long long state = 88172645463325252ULL;
static unsigned long long next_key(void) { /* xorshift64: 48-bit keys */
state ^= state << 13; state ^= state >> 7; state ^= state << 17;
return state >> 16;
}
static long table[M]; /* open addressing: 0 means empty */
static int head[M], nxt[M]; /* chaining: nodes are numbered 1 ..., stored keys in node_key */
static long node_key[M + 1];
/* the three tables, with the number of array slots or list nodes examined by a search */
static int probes_open(long key, int double_hashing) {
int h1 = (int)(key % M), h2 = double_hashing ? 1 + (int)(key % (M - 1)) : 1;
int p = 0;
for (int i = 0; i < M; i++) {
int idx = (int)(((long)h1 + (long)i * h2) % M);
p++;
if (table[idx] == 0 || table[idx] == key) return p;
}
return p;
}
static void insert_open(long key, int double_hashing) {
int h1 = (int)(key % M), h2 = double_hashing ? 1 + (int)(key % (M - 1)) : 1;
for (int i = 0; i < M; i++) {
int idx = (int)(((long)h1 + (long)i * h2) % M);
if (table[idx] == 0) { table[idx] = key; return; }
}
}
static int probes_chain(long key) {
int p = 0;
for (int node = head[key % M]; node; node = nxt[node]) {
p++;
if (node_key[node] == key) return p;
}
return p;
}
int main(void) {
double loads[3] = {0.5, 0.8, 0.9};
printf("%-9s %5s %12s %14s\n", "scheme", "alpha", "successful", "unsuccessful");
for (int scheme = 0; scheme < 3; scheme++) { /* 0 chaining, 1 linear probing, 2 double hashing */
for (int a = 0; a < 3; a++) {
int n = (int)(loads[a] * M);
double succ = 0, miss = 0;
for (int trial = 0; trial < TRIALS; trial++) {
long *keys = malloc(sizeof(long) * n);
for (int i = 0; i < M; i++) { table[i] = 0; head[i] = 0; }
for (int i = 0; i < n; i++) {
keys[i] = (long)next_key() + 1;
if (scheme == 0) { node_key[i + 1] = keys[i]; nxt[i + 1] = head[keys[i] % M]; head[keys[i] % M] = i + 1; }
else insert_open(keys[i], scheme == 2);
}
long total = 0;
for (int i = 0; i < n; i++) total += scheme == 0 ? probes_chain(keys[i]) : probes_open(keys[i], scheme == 2);
succ += (double)total / n;
total = 0;
for (int q = 0; q < MISSES; q++) {
long key = (long)next_key() + 1;
total += scheme == 0 ? probes_chain(key) : probes_open(key, scheme == 2);
}
miss += (double)total / MISSES;
free(keys);
}
printf("%-9s %5.2f %12.3f %14.3f\n", scheme == 0 ? "chaining" : scheme == 1 ? "linear" : "double", loads[a], succ / TRIALS, miss / TRIALS);
}
}
return 0;
}scheme alpha successful unsuccessful
chaining 0.50 1.252 0.505
chaining 0.80 1.402 0.802
chaining 0.90 1.447 0.898
linear 0.50 1.505 2.500
linear 0.80 3.049 13.258
linear 0.90 5.640 52.883
double 0.50 1.388 1.994
double 0.80 2.002 4.985
double 0.90 2.548 9.994Measured probes against the formulas (10007 slots): start
Computed by a script, not typed| scheme and load | successful: measured | successful: formula | unsuccessful: measured | unsuccessful: formula |
|---|---|---|---|---|
| chaining, alpha = 0.50 | ||||
| chaining, alpha = 0.80 | ||||
| chaining, alpha = 0.90 | ||||
| linear, alpha = 0.50 | ||||
| linear, alpha = 0.80 | ||||
| linear, alpha = 0.90 | ||||
| double, alpha = 0.50 | ||||
| double, alpha = 0.80 | ||||
| double, alpha = 0.90 |
Step 0
Random keys were inserted into tables of 10007 slots until the load factor reached 0.5, 0.8 and 0.9, and the number of slots or list nodes examined was averaged over every successful search and over 20000 unsuccessful searches (5 tables each).
Chaining stays near and whatever the load. Double hashing follows and : and at , and at . In probe counts linear probing is worse than double hashing at every load shown, and at an unsuccessful search needs about probes against . Its advantage in practice is cache locality (consecutive slots), which probe counts do not capture.
Other expectations under uniform hashing
- Colliding pairs. Among keys the expected number of pairs that hash to the same slot is (each pair collides with probability , then add by linearity of expectation).
- Empty slots. A given slot is empty after insertions with probability , so the expected number of empty slots is : with about of the slots remain empty, even though the table has as many keys as slots.
- Longest chain. With the expected length of the longest chain is (a result from the literature, not derived here), more than constant but far below .
- Resizing. To keep below a threshold, the table is doubled when it gets too full and everything is rehashed; since doubling happens after exponentially growing numbers of insertions, the amortized cost of an insertion remains constant.
Worked examples
EX 1Chaining: expected comparisons
EasyA table with slots holds keys with chaining. . An unsuccessful search examines on average nodes; a successful one examines about . Doubling the table to gives : nodes for an unsuccessful and about for a successful search.
EX 2Open addressing with uniform hashing
Easy: an unsuccessful search or an insertion needs at most probes on average; a successful one . If the table is full the bounds are and . A table that is full needs at most probes for an insertion.
EX 3Linear probing against double hashing
MediumAt : linear probing needs probes for an unsuccessful search and for a successful one; double hashing needs and . So a table that is full is already costly for unsuccessful searches in linear probing. This is why open addressing is kept below about to .
EX 4Expected empty slots and collisions
MediumHash random keys into slots. Expected number of colliding pairs: . Expected number of empty slots: (exactly ). So about slots are used, and the remaining keys share slots with others. (For , : all assignments give on average empty slots, which agrees with the formula.)
EX 5Expected cost questions
GATE level(a) A hash table with chaining has slots and keys. Expected cost of an unsuccessful search? comparisons (). (b) Open addressing, : expected probes of an unsuccessful search? At most . (c) Why does the expected search time of a hash table with chaining stay as grows? Because is increased in proportion to (resizing), keeping bounded. (d) Maximum possible load factor of open addressing: (the table full), at which point an unsuccessful search never finds an empty slot and examines all slots. (e) Expected number of keys needed before the first collision when is large: about (the mean), the median being .
Cheat box
Cheat box
- Load factor . Chaining: unsuccessful (or ), successful ; both ; worst .
- Open addressing, uniform hashing / double hashing: unsuccessful and insert ; successful .
- Linear probing: unsuccessful , successful .
- Values: : (uniform), (linear); : (uniform), (linear).
- Expected colliding pairs ; expected empty slots .
- Keep by resizing; open addressing needs , and in practice to .
Traps and GATE patterns
Connections
Builds on
Across subjects
Within this subject
The collision-handling schemes analysed here are defined in chaining and open addressing and the functions in hashing. The probability tools (expectation, linearity) are those of expectation of random variables.
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
Suppose we are given n keys, m hash table slots, and
Consider a hash table with 9 slots. The hash function is h(k) = k mod 9. The collisions are resolved by chaining. The following 9 keys are inserted in the order: 5, 28, 19, 15, 20, 33, 12, 17, 10. The maximum, minimum, and average chain lengths in the hash table, respectively, are
- (a)3,0,and 1
- (b)3,3,and 3
- (c)4,0,and 1
- (d)3,0,and 2
Consider a hash table with 100 slots. Collisions are resolved using chaining. Assuming simple uniform DATA STRUCTURE hashing, what is the probability that the first 3 slots are unfilled after the first 3 insertions?
- (a)(97 x 97 x 97)/1003
- (b)(99 x 98 x 97)/1003
- (c)(97 x 96 x 95)/1003
- (d)(97 x 96 x 95)/(3! x 1003)
Self-check
Question 1
A chained hash table has slots and holds keys. Expected number of nodes examined in an unsuccessful search?
Show answerHide
.
Question 2
An open addressing table is full and uses uniform hashing. Bound on the expected probes of an insertion?
Show answerHide
.
Question 3
Which has the larger expected unsuccessful search cost at : linear probing or double hashing?
Show answerHide
Linear probing (about ) against double hashing (about ).
Question 4
keys are hashed into slots uniformly. What is the expected number of pairs of keys in the same slot?
Show answerHide
.
Revision card
One-screen revision
- Chaining: / (unsuccessful / successful); .
- Open addressing (uniform): and .
- Linear probing: and .
- Colliding pairs ; empty slots ; resize to keep constant.
References
- ·Cormen, Leiserson, Rivest, Stein, Introduction to Algorithms (3rd edition), Chapter 11 Hash Tables (Theorems 11.1, 11.2 on chaining; Theorems 11.6, 11.8 on open addressing)
- ·Knuth, The Art of Computer Programming, Volume 3, Section 6.4 Hashing (analysis of linear probing)
- ·Sedgewick and Wayne, Algorithms (4th edition), Section 3.4 (Proposition M for linear probing)
Verification
The expectations were verified by exact enumeration of all m^n hash assignments for small m, n (chaining: unsuccessful n/m and successful 1 + (n-1)/(2m); empty slots m(1 - 1/m)^n; colliding pairs C(n,2)/m) and, for uniform probing, by exact rational arithmetic for every m below 30 and every n: the unsuccessful expectation equals (m+1)/(m-n+1), which is at most 1/(1-alpha), and the successful one equals ((m+1)/n)(H_(m+1) - H_(m-n+1)), which is close to (1/alpha) ln(1/(1-alpha)) for large m. The linear probing formulas of Knuth are asymptotic results; they were checked by simulation (C program on this page, and an independent Python simulation) and agree within a few percent at load factors 0.5, 0.8 and 0.9. Double hashing was simulated and follows the uniform hashing formulas. Textbook theorem numbers are from memory. The expected longest chain Theta(log n / log log n) is quoted from the literature and was not tested. 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)