G27
Self-checkedTier 1 13 min readalgo.hashing-analysis

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 α=n/m\alpha = n/m 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 α\alpha. This page derives the formulas, checks them against measurements, and shows how quickly open addressing degrades as α→1\alpha \to 1.

Prerequisites

Chaining and open addressing
Random variables, expectation and varianceplanned

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. α=n/m\alpha = n/m, with nn keys in mm slots. For open addressing 0≤α<10 \le \alpha < 1; for chaining α\alpha may exceed 11.

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 m!m! 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 n/m=αn/m = \alpha nodes on average, and an unsuccessful search examines all of them: α\alpha nodes (plus the constant work of computing hh). A successful search ends at the sought key. Suppose the keys were inserted at the front of their lists. The ii-th inserted key is preceded in its list by exactly the keys inserted after it that hash to the same slot; each of the n−in - i later keys does so with probability 1/m1/m, so the expected number of nodes examined to find it is 1+(n−i)/m1 + (n - i)/m. Averaging over i=1,…,ni = 1, \ldots, n: 1+1n∑i=1nn−im=1+n−12m=1+α2−α2n.1 + \frac{1}{n} \sum_{i=1}^{n} \frac{n - i}{m} = 1 + \frac{n - 1}{2m} = 1 + \frac{\alpha}{2} - \frac{\alpha}{2n}. So a successful search costs about 1+α/21 + \alpha/2, an unsuccessful one α\alpha (or 1+α1 + \alpha counting the access of the slot). Both are Θ(1+α)\Theta(1 + \alpha): constant if n=O(m)n = O(m), which is why mm is chosen proportional to nn. These two formulas were confirmed by enumerating every assignment of keys to slots for small mm and nn. The worst case is Θ(n)\Theta(n) (all keys in one list).

Open addressing with uniform hashing

Consider an unsuccessful search in a table with nn keys in mm slots. It makes more than ii probes exactly when the first ii slots of its (random) probe sequence are all occupied, which has probability nm⋅n−1m−1⋯n−i+1m−i+1  ≤  α i.\frac{n}{m} \cdot \frac{n-1}{m-1} \cdots \frac{n-i+1}{m-i+1} \;\le\; \alpha^{\,i}. The expected number of probes is the sum of the probabilities of "more than ii probes" for i=0,1,2,…i = 0, 1, 2, \ldots, so E[unsuccessful]  ≤  ∑i≥0αi=11−α.E[\text{unsuccessful}] \;\le\; \sum_{i \ge 0} \alpha^{i} = \frac{1}{1 - \alpha}. (Exactly it equals (m+1)/(m−n+1)(m + 1)/(m - n + 1).) 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 (j+1)(j+1)-th to be inserted found jj keys already present and needed at most 1/(1−j/m)1/(1 - j/m) probes on average, so E[successful]  ≤  1n∑j=0n−1mm−j  ≈  1α∫0αdx1−x=1αln⁡11−α.E[\text{successful}] \;\le\; \frac{1}{n} \sum_{j=0}^{n-1} \frac{m}{m - j} \;\approx\; \frac{1}{\alpha} \int_0^{\alpha} \frac{dx}{1 - x} = \frac{1}{\alpha} \ln \frac{1}{1 - \alpha}. Values: at α=0.5\alpha = 0.5 an unsuccessful search needs 22 probes and a successful one 1.391.39; at 0.90.9 they need 1010 and 2.562.56; at 0.990.99 they need 100100 and 4.654.65. 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 E[successful]≈12(1+11−α),E[unsuccessful]≈12(1+1(1−α)2).E[\text{successful}] \approx \tfrac12\left(1 + \frac{1}{1 - \alpha}\right), \qquad E[\text{unsuccessful}] \approx \tfrac12\left(1 + \frac{1}{(1 - \alpha)^2}\right). At α=0.5\alpha = 0.5: 1.51.5 and 2.52.5 probes. At α=0.8\alpha = 0.8: 33 and 1313. At α=0.9\alpha = 0.9: 5.55.5 and 50.550.5. Compare with 1010 for uniform hashing at 0.90.9: the square in the denominator is the price of clustering.

Measured

The C program fills tables of 1000710007 slots with random keys up to a given load factor and averages the probes of every successful search and of 2000020000 unsuccessful searches, over 55 tables for each setting, for chaining, linear probing and double hashing (with h2(k)=1+k mod (m−1)h_2(k) = 1 + k \bmod (m - 1)).

#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.994

Measured probes against the formulas (10007 slots): start

Computed by a script, not typed
scheme and loadsuccessful: measuredsuccessful: formulaunsuccessful: measuredunsuccessful: 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).

0 / 9
computed by script: the quantities are measured by running C, or evaluated, one row at a time. python3 scripts/gen-algo-hash-traces.py

Chaining stays near α\alpha and 1+α/21 + \alpha/2 whatever the load. Double hashing follows 1/(1−α)1/(1 - \alpha) and (1/α)ln⁡(1/(1−α))(1/\alpha)\ln(1/(1 - \alpha)): 22 and 1.391.39 at 0.50.5, 1010 and 2.562.56 at 0.90.9. In probe counts linear probing is worse than double hashing at every load shown, and at α=0.9\alpha = 0.9 an unsuccessful search needs about 5050 probes against 1010. Its advantage in practice is cache locality (consecutive slots), which probe counts do not capture.

Other expectations under uniform hashing

  • Colliding pairs. Among nn keys the expected number of pairs that hash to the same slot is (n2)/m\binom{n}{2}/m (each pair collides with probability 1/m1/m, then add by linearity of expectation).
  • Empty slots. A given slot is empty after nn insertions with probability (1−1/m)n≈e−α(1 - 1/m)^n \approx e^{-\alpha}, so the expected number of empty slots is m(1−1/m)n≈me−αm(1 - 1/m)^n \approx m e^{-\alpha}: with n=mn = m about 37%37\% of the slots remain empty, even though the table has as many keys as slots.
  • Longest chain. With n=mn = m the expected length of the longest chain is Θ(log⁡n/log⁡log⁡n)\Theta(\log n / \log \log n) (a result from the literature, not derived here), more than constant but far below nn.
  • Resizing. To keep α\alpha 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

Easy

A table with m=100m = 100 slots holds n=250n = 250 keys with chaining. α=2.5\alpha = 2.5. An unsuccessful search examines on average 2.52.5 nodes; a successful one examines about 1+2.5/2−2.5/500≈2.2451 + 2.5/2 - 2.5/500 \approx 2.245. Doubling the table to m=200m = 200 gives α=1.25\alpha = 1.25: 1.251.25 nodes for an unsuccessful and about 1.621.62 for a successful search.

EX 2Open addressing with uniform hashing

Easy

α=0.75\alpha = 0.75: an unsuccessful search or an insertion needs at most 1/(1−0.75)=41/(1 - 0.75) = 4 probes on average; a successful one 10.75ln⁡4=1.85\frac{1}{0.75} \ln 4 = 1.85. If the table is 90%90\% full the bounds are 1010 and 2.562.56. A table that is 50%50\% full needs at most 22 probes for an insertion.

EX 3Linear probing against double hashing

Medium

At α=0.8\alpha = 0.8: linear probing needs 12(1+10.22)=12(1+25)=13\frac12\left(1 + \frac{1}{0.2^2}\right) = \frac12(1 + 25) = 13 probes for an unsuccessful search and 12(1+5)=3\frac12(1 + 5) = 3 for a successful one; double hashing needs 55 and 2.012.01. So a table that is 80%80\% full is already costly for unsuccessful searches in linear probing. This is why open addressing is kept below about α=0.5\alpha = 0.5 to 0.70.7.

EX 4Expected empty slots and collisions

Medium

Hash n=1000n = 1000 random keys into m=1000m = 1000 slots. Expected number of colliding pairs: (10002)/1000=499.5\binom{1000}{2}/1000 = 499.5. Expected number of empty slots: 1000(1−1/1000)1000≈1000⋅e−1≈3681000 (1 - 1/1000)^{1000} \approx 1000 \cdot e^{-1} \approx 368 (exactly 367.7367.7). So about 632632 slots are used, and the remaining 368368 keys share slots with others. (For m=3m = 3, n=3n = 3: all 2727 assignments give on average 3(2/3)3=8/93 (2/3)^3 = 8/9 empty slots, which agrees with the formula.)

EX 5Expected cost questions

GATE level

(a) A hash table with chaining has mm slots and n=2mn = 2m keys. Expected cost of an unsuccessful search? α=2\alpha = 2 comparisons (Θ(1)\Theta(1)). (b) Open addressing, α=0.5\alpha = 0.5: expected probes of an unsuccessful search? At most 22. (c) Why does the expected search time of a hash table with chaining stay O(1)O(1) as nn grows? Because mm is increased in proportion to nn (resizing), keeping α\alpha bounded. (d) Maximum possible load factor of open addressing: 11 (the table full), at which point an unsuccessful search never finds an empty slot and examines all mm slots. (e) Expected number of keys needed before the first collision when mm is large: about 1.25m1.25 \sqrt m (the mean), the median being 1.18m1.18 \sqrt m.

Cheat box

Cheat box

  • Load factor α=n/m\alpha = n/m. Chaining: unsuccessful α\alpha (or 1+α1 + \alpha), successful 1+α/2−α/(2n)≈1+α/21 + \alpha/2 - \alpha/(2n) \approx 1 + \alpha/2; both Θ(1+α)\Theta(1 + \alpha); worst Θ(n)\Theta(n).
  • Open addressing, uniform hashing / double hashing: unsuccessful and insert ≤1/(1−α)\le 1/(1 - \alpha); successful ≤1αln⁡11−α\le \frac{1}{\alpha} \ln \frac{1}{1 - \alpha}.
  • Linear probing: unsuccessful 12(1+1(1−α)2)\frac12\left(1 + \frac{1}{(1-\alpha)^2}\right), successful 12(1+11−α)\frac12\left(1 + \frac{1}{1 - \alpha}\right).
  • Values: α=0.5\alpha = 0.5: 2,1.392, 1.39 (uniform), 2.5,1.52.5, 1.5 (linear); α=0.9\alpha = 0.9: 10,2.5610, 2.56 (uniform), 50.5,5.550.5, 5.5 (linear).
  • Expected colliding pairs (n2)/m\binom{n}{2}/m; expected empty slots m(1−1/m)n≈me−αm(1 - 1/m)^n \approx m e^{-\alpha}.
  • Keep m=Θ(n)m = \Theta(n) by resizing; open addressing needs α<1\alpha < 1, and in practice α≤0.5\alpha \le 0.5 to 0.70.7.

Traps and GATE patterns

Connections

Across subjects

Random variables, expectation and varianceusesplanned

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

year not read yetQ5 · page 88 of the book
Suppose we are given n keys, m hash table slots, and
GATE 2014 · Set 1Q11 · page 89 of the book
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
GATE 2014 · Set 3Q12 · page 89 of the book
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 m=50m = 50 slots and holds 100100 keys. Expected number of nodes examined in an unsuccessful search?

Show answer

α=2\alpha = 2.

Question 2

An open addressing table is 80%80\% full and uses uniform hashing. Bound on the expected probes of an insertion?

Show answer

1/(1−0.8)=51/(1 - 0.8) = 5.

Question 3

Which has the larger expected unsuccessful search cost at α=0.9\alpha = 0.9: linear probing or double hashing?

Show answer

Linear probing (about 50.550.5) against double hashing (about 1010).

Question 4

nn keys are hashed into mm slots uniformly. What is the expected number of pairs of keys in the same slot?

Show answer

(n2)/m\binom{n}{2}/m.

Revision card

One-screen revision

  • Chaining: α\alpha / 1+α/21 + \alpha/2 (unsuccessful / successful); Θ(1+α)\Theta(1 + \alpha).
  • Open addressing (uniform): ≤1/(1−α)\le 1/(1 - \alpha) and 1αln⁡11−α\frac1\alpha \ln \frac{1}{1 - \alpha}.
  • Linear probing: 12(1+1/(1−α)2)\frac12(1 + 1/(1-\alpha)^2) and 12(1+1/(1−α))\frac12(1 + 1/(1-\alpha)).
  • Colliding pairs (n2)/m\binom{n}{2}/m; empty slots ≈me−α\approx m e^{-\alpha}; resize to keep α\alpha 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