Algorithm Search⌘K

Proofs: Robin Hood hashing

These are the human proofs of Robin Hood hashing, at full length.

Robin Hood hashing keeps its invariant, finds each key, and minimizes the sum of squared distances full

This proof shows: correctness, termination.

All slot indices are taken modulo mm. A slot is full when it holds a key. For a full slot jj, write T[j]T[j] for its key and D[j]D[j] for the stored distance. A table is valid when (a) no key occurs twice, (b) for each full slot jj, D[j]=(j−h(T[j])) mod mD[j] = (j - h(T[j])) \bmod m, (c) at least one slot is EMPTY, and (d) the invariant (R) holds:

(R) For each full slot jj with D[j]>0D[j] > 0, slot j−1j - 1 is full and D[j−1]≥D[j]−1D[j-1] \ge D[j] - 1.

Lemma 1 (paths are full). In a valid table, let slot ss hold xx with distance tt. Then for each u=0,…,tu = 0, \ldots, t, the slot h(x)+u=s−(t−u)h(x) + u = s - (t - u) is full and its distance is at least uu.

Proof. By induction on t−ut - u. For u=tu = t, slot ss is full with distance tt. If slot s−(t−u)s - (t-u) is full with distance e≥ue \ge u and u≥1u \ge 1, then e>0e > 0, so by (R) slot s−(t−u)−1s - (t - u) - 1 is full with distance at least e−1≥u−1e - 1 \ge u - 1. □\square

Lemma 1 gives t+1t + 1 full slots, and at most m−1m - 1 slots are full, so each distance in a valid table is at most m−2m - 2.

Lemma 2 (search). In a valid table, RH-SEARCH(T,k)(T, k) returns the slot of kk if kk is in TT, and NIL otherwise. It makes at most mm probes.

Proof. In the iteration with distance dd, the loop looks at slot j=h(k)+dj = h(k) + d (line L1 and line L5). It returns a slot only at line L4, where T[j]=kT[j] = k, so if kk is absent the result is NIL. Each iteration increases dd by 1. All stored distances are at most m−2m - 2, so in the iteration with d=m−1d = m - 1 line L3 returns, if no earlier line did. So the loop makes at most mm probes.

Now let kk be at slot s=h(k)+ts = h(k) + t, with distance tt. For d<td < t, Lemma 1 with u=du = d shows that slot h(k)+dh(k) + d is full with distance at least dd, so line L3 does not return. That slot does not hold kk, because kk occurs only once, at s≠h(k)+ds \ne h(k) + d (as 0≤d<t≤m−10 \le d < t \le m - 1). So line L4 does not return either. At d=td = t, slot ss holds kk with D[s]=tD[s] = t, so line L3 does not return and line L4 returns ss. □\square

Lemma 3 (insertion). If the table is valid, kk is not in it, and at least two slots are EMPTY, then RH-INSERT(T,k)(T, k) ends, the new table is valid, and it holds the old keys and kk. The slot that becomes full is the first EMPTY slot at or after h(k)h(k).

Proof. Call the pair (x,d)(x, d) the key in the hand at slot jj, at the test of line L8. We prove that at each such test these statements hold:

  1. The keys in the table, with xx, are the old keys and kk, each once.
  2. d=(j−h(x)) mod md = (j - h(x)) \bmod m, and (b) holds for each full slot.
  3. (R) holds for the table.
  4. If d>0d > 0, slot j−1j - 1 is full and D[j−1]≥d−1D[j-1] \ge d - 1.
  5. Exactly the slots that were full before the call are full now.

At the first test, x=kx = k, j=h(k)j = h(k) and d=0d = 0, and the table is the old one, so 1 to 5 hold.

Suppose that 1 to 5 hold at the test, and slot jj is full, so line L8 does not return. Two cases follow.

Case D[j]≥dD[j] \ge d. Line L9 does nothing. Line L10 moves to j+1j + 1 with distance d+1d + 1, which keeps statement 2 for xx. Statement 4 at the new position needs slot jj full with D[j]≥dD[j] \ge d, which is the case. Statements 1, 3 and 5 do not change.

Case D[j]=e<dD[j] = e < d. Line L9 writes (x,d)(x, d) into slot jj and takes (T[j],e)(T[j], e) in the hand. Statement 1 is kept, and (b) holds at slot jj by statement 2. (R) at slot jj: as d>e≥0d > e \ge 0, statement 4 gives slot j−1j-1 full with D[j−1]≥d−1D[j-1] \ge d - 1. (R) at slot j+1j + 1: if it is full with D[j+1]=f>0D[j+1] = f > 0, then the old (R) gave e≥f−1e \ge f - 1, so d>e≥f−1d > e \ge f - 1. (R) at other slots is unchanged. Line L10 moves to j+1j + 1 with distance e+1e + 1, which is the distance of the new key in the hand at j+1j + 1, and statement 4 holds because slot jj is full with D[j]=d>eD[j] = d > e. Statement 5 is kept because the same slots are full.

Now suppose the test of line L8 finds slot jj EMPTY. Line L8 writes (x,d)(x, d) there and returns. Statement 1 gives the key set. (b) holds at jj by statement 2. (R) at slot jj holds by statement 4. (R) at slot j+1j + 1: before the write, slot jj was EMPTY, so by (R) a full slot j+1j + 1 had distance 0, and (R) asks nothing for it. So the table is valid, except possibly (c). By statement 5 only the slot jj became full, and two slots were EMPTY, so one is still EMPTY.

Termination: between two tests, jj moves one slot to the right and statement 5 says the full slots do not change. There is an EMPTY slot, so after at most m−1m - 1 moves the test meets it. Because jj moves one slot at a time from h(k)h(k), the slot that becomes full is the first EMPTY slot at or after h(k)h(k). □\square

Lemma 4 (deletion). If the table is valid, RH-DELETE(T,k)(T, k) removes kk if it is present, keeps all other keys, and leaves a valid table.

Proof. By Lemma 2, line L11 finds the slot j0j_0 of kk or NIL. If NIL, nothing changes. Otherwise let j0+1,…,j0+rj_0 + 1, \ldots, j_0 + r be the longest block of full slots after j0j_0 in which each distance is positive, with r≥0r \ge 0. As one slot is EMPTY, r≤m−2r \le m - 2. Slot j0+r+1j_0 + r + 1 is EMPTY or holds a key with distance 0. The loop of lines L14 to L16 copies the entry of slot j0+qj_0 + q to slot j0+q−1j_0 + q - 1 with distance one less, for q=1,…,rq = 1, \ldots, r, and line L17 makes slot j0+rj_0 + r EMPTY. The key kk is overwritten (or, if r=0r = 0, its slot is emptied), and each other key moves at most once, so the key set is the old one without kk.

(b): a key moved one slot left gets its distance lowered by 1, which is right, and the old distance was at least 1, so the new one is at least 0.

(R): let yqy_q be the key that was at j0+qj_0 + q, with old distance eq>0e_q > 0, for 1≤q≤r1 \le q \le r. Inside the block, for 2≤q≤r2 \le q \le r, the old (R) gave eq−1≥eq−1e_{q-1} \ge e_q - 1, and both values drop by 1, so (R) holds between the new slots j0+q−2j_0 + q - 2 and j0+q−1j_0 + q - 1. At the new slot j0j_0 (key y1y_1, distance e1−1e_1 - 1): if e1−1>0e_1 - 1 > 0, the old (R) at j0+1j_0 + 1 gave D[j0]≥e1−1>0D[j_0] \ge e_1 - 1 > 0 for the old key kk; then the old (R) at j0j_0 gave slot j0−1j_0 - 1 full with distance at least D[j0]−1≥e1−2D[j_0] - 1 \ge e_1 - 2, which is what (R) asks. Slot j0−1j_0 - 1 is not changed by the shift, because r≤m−2r \le m - 2. Slot j0+rj_0 + r is now EMPTY, and slot j0+r+1j_0 + r + 1 is EMPTY or has distance 0, so (R) asks nothing there. Other slots do not change. (c) holds because the number of EMPTY slots grows by one. □\square

Theorem 1 (correctness). Start from an EMPTY table with m≥2m \ge 2 slots, and apply RH-INSERT (for a key that is not present, with at least two EMPTY slots), RH-DELETE and RH-SEARCH in any order. Then each table is valid, the set of keys is the one given by the operations, and each search answers correctly. Each operation ends after O(m)O(m) steps.

Proof. The EMPTY table is valid. Lemmas 3 and 4 keep validity and give the key set, by induction on the number of operations, and Lemma 2 gives the answer and the bound for search. The loop of RH-DELETE moves over at most r≤m−2r \le m - 2 slots. ■\blacksquare

The sum of the distances and the sum of their squares

Fix a set KK of n<mn < m keys. Call an assignment of the keys to distinct slots a linear probing layout when, for each key xx at slot ss, every slot from h(x)h(x) to ss (going right) is full. Its distance is d(x)=(s−h(x)) mod md(x) = (s - h(x)) \bmod m. By Lemma 1, each valid Robin Hood table is a linear probing layout.

Theorem 2. Let LL and L′L' be two linear probing layouts of KK with the same set FF of full slots. Then ∑xdL(x)=∑xdL′(x)\sum_{x} d_L(x) = \sum_x d_{L'}(x). If LL is a valid Robin Hood table, then ∑xdL(x)2≤∑xdL′(x)2\sum_x d_L(x)^2 \le \sum_x d_{L'}(x)^2.

Proof. For a slot ss, let a(s)a(s) be the number of keys with h(x)=sh(x) = s, let o(s)=1o(s) = 1 if s∈Fs \in F and 0 otherwise, and let c(s)c(s) be the number of keys whose path from h(x)h(x) to its slot contains both ss and s+1s + 1. A key at distance dd crosses exactly dd such boundaries, so ∑xd(x)=∑sc(s)\sum_x d(x) = \sum_s c(s).

The keys whose path contains ss are the keys with home ss and the keys that cross the boundary from s−1s - 1 to ss; these are disjoint, because a path is shorter than mm. Of these keys, exactly o(s)o(s) sit at ss, and the others cross to s+1s + 1. So c(s)=c(s−1)+a(s)−o(s)c(s) = c(s-1) + a(s) - o(s). If s∉Fs \notin F, no path contains ss, so c(s)=0c(s) = 0. Pick s0∉Fs_0 \notin F, which exists because n<mn < m. Then c(s0)=0c(s_0) = 0, and the recursion gives c(s0+1),c(s0+2),…c(s_0 + 1), c(s_0 + 2), \ldots from aa and oo only. So cc, and with it the sum of distances, is the same for LL and L′L'.

For the squares, cut the circle at s0s_0 and number the slots s0+1,…,s0+m−1s_0 + 1, \ldots, s_0 + m - 1 as 1,…,m−11, \ldots, m - 1. No path contains s0s_0, so each path lies in this range and is an interval [h(x),s][h(x), s] of integers, with d(x)=s−h(x)d(x) = s - h(x). Suppose a layout L′L' has keys xx at slot pp and yy at slot qq with p<qp < q and h(x)>h(y)h(x) > h(y). Swap them. Then yy is at pp with h(y)<h(x)≤ph(y) < h(x) \le p, and xx is at q>p≥h(x)q > p \ge h(x), and the set of full slots is the same, so the result is again a linear probing layout with full set FF. The change in the sum of squares is

(p−h(y))2+(q−h(x))2−(p−h(x))2−(q−h(y))2=−2(q−p)(h(x)−h(y))<0.(p - h(y))^2 + (q - h(x))^2 - (p - h(x))^2 - (q - h(y))^2 = -2(q - p)(h(x) - h(y)) < 0.

The number of layouts is finite, so a layout with the least sum of squares exists, and by the swap it has no such pair: its homes do not decrease from left to right. Call such a layout sorted. In a sorted layout, the slots in FF are filled from left to right by the keys in order of home, so the multiset of distances is the same for every sorted layout (keys with equal homes can trade places without a change of distances). So every sorted layout has the least sum of squares.

A valid Robin Hood table is sorted. Take two full slots s<s′s < s' in the range. If all slots from ss to s′s' are full, it is enough to look at s′=s+1s' = s + 1. If D[s+1]>0D[s+1] > 0, (R) gives h(T[s+1])=s+1−D[s+1]≥s+1−(D[s]+1)=h(T[s])h(T[s+1]) = s + 1 - D[s+1] \ge s + 1 - (D[s] + 1) = h(T[s]). If D[s+1]=0D[s+1] = 0, then h(T[s+1])=s+1>s≥h(T[s])h(T[s+1]) = s + 1 > s \ge h(T[s]). If an EMPTY slot ee lies between ss and s′s', the path of T[s′]T[s'] does not contain ee, so h(T[s′])>e>s≥h(T[s])h(T[s']) > e > s \ge h(T[s]). ■\blacksquare

Consequence. Lemma 3 shows that RH-INSERT fills the first EMPTY slot at or after the home slot, as plain linear probing does. So the two methods, run on the same sequence of insertions, have the same set of full slots after each step. By Theorem 2 they have the same mean distance, and Robin Hood has the least variance of the distance among all linear probing layouts with these full slots.

Back to Robin Hood hashing