Proofs: Coalesced hashing
These are the human proofs of Coalesced hashing, at full length.
Cost of coalesced hashing sketch
This proof shows: time.worst, time.expected.
Worst case (full proof). A search or insert of key visits the slots of one walk from , and by the lemma of the correctness proof this walk has at most slots. So each search costs , and each insert costs plus the passes of line L7. The pointer starts at , only decreases, and line L7 decreases it by one at each pass, so all inserts together make at most passes of line L7. For the lower bound, let all keys have the same home slot. The first key fills the home slot, and each later key is appended at the end of the one chain, so the -th insert visits slots of the chain, and a search for the last key visits slots. Hence the worst case of a single operation is , plus for the moves of over all inserts.
Expected case (sketch, after Knuth, Section 6.4). Assume that the keys have independent uniform home slots. The analysis of Algorithm C rests on two facts.
- The chains form a set of disjoint linked lists that cover the occupied slots, and the cost of a search that fails from home slot is 1 if slot is EMPTY, and else the number of slots from to the end of the list that contains .
- A new key whose home slot lies on a list of slots, which happens with probability , adds one slot to that list: the free slot that line L7 takes. That slot may later be the home slot of another key, and this is how two lists merge. Counting the expected number of lists of each length leads to a recurrence on that Knuth solves.
The result, as with , is expected probes for a search that fails, and for a search that succeeds. Both are at most their values at , about 2.10 and 1.80, so the expected cost is for each . The full derivation is in Knuth, The Art of Computer Programming, Volume 3, Section 6.4, in the analysis of Algorithm C, and the variants with a cellar are analysed in Vitter, Journal of the ACM 30(2), 1983, pages 231 to 258.
Coalesced hashing keeps its chains and implements insert and search full
This proof shows: correctness, termination.
A slot is occupied when EMPTY. Write when . The invariant is:
- (C1) for each occupied slot with key , the slot is occupied, and is reached from by a path with ;
- (C2) if , then and are occupied; each slot has at most one incoming link; and there is no cycle ;
- (C3) no key is in two slots;
- (C4) each slot with is occupied, and .
Lemma (walks end). Under (C2), the walk from an occupied slot reaches a slot with $\mathit{next} = $ NIL after at most steps, and it visits no slot twice.
Proof. Each slot of the walk is occupied by (C2). If the walk visited a slot twice, the part between the two visits would be a cycle, which (C2) forbids. So it visits distinct occupied slots, at most of them, and it can only stop at a NIL link.
Theorem. Start from the table with all slots EMPTY, all links NIL and , and apply any sequence of COALESCED-INSERT and COALESCED-SEARCH. Each call terminates. After each call (C1) to (C4) hold, and the set of stored pairs is the map that the same sequence gives on an abstract dictionary, except that an insert of a new key into a full table reports an error and changes nothing. Each search returns the value of its key, or NIL if the key is absent.
Proof. At the start no slot is occupied and , so the invariant holds. Assume it before a call on key , and let .
Search. If slot is EMPTY, then by (C1) no stored key has home , so is absent and line L12 is right. Otherwise lines L13 to L15 walk from , and by the lemma the walk ends after at most slots. If is stored, then by (C1) its slot is on the path from , and since each slot has at most one outgoing link this path is a prefix of the walk, so line L14 finds it; by (C3) the value is the value of . If the walk ends without , then is absent and line L16 is right. Search changes nothing.
Insert, home slot free. If slot is EMPTY, line L2 stores there with a NIL link. By (C1) no stored key had home , so in particular was absent and (C3) holds. (C1) holds for with , and for the other keys their paths did not change. The new slot has no links, so (C2) holds. (C4) holds: a slot was filled and did not change.
Insert, home slot occupied. Lines L3 to L6 walk from ; the walk ends by the lemma. As in the search, if is stored, line L4 finds it and only its value changes, so the invariant holds. Otherwise is absent, and the walk stops at the last slot of the walk, with $\mathit{next}[i] = $ NIL.
Line L7 lowers by at least 1 and stops at the first EMPTY slot below the old , or at . The slots it passes over are occupied, so (C4) holds for the new as long as . If , every slot is occupied by (C4) and the passes of line L7, so the table is full, is absent, and line L8 reports it. (The program then sets , which keeps (C4).)
Else slot is EMPTY. By (C2) it has no incoming link (only occupied slots have links, and links point to occupied slots) and its own link is NIL. Line L9 sets , and line L10 stores in slot with a NIL link. Then:
- (C1) holds for , by the path from to followed by . It holds for each other key, because no old link changed except , which was NIL and so was the end of each path through .
- (C2) holds. Both ends of the new link are occupied. Slot had no incoming link, so it now has one. No cycle appears: a cycle through the new link would need a path from back to , but $\mathit{next}[r] = $ NIL.
- (C3) holds since was absent.
- (C4) holds since slot is now occupied.
The stored map gains exactly .
Termination. Each walk ends by the lemma. The loop of line L7 lowers by 1 at each pass and stops at at the latest, so it ends after at most passes.
By induction on the number of calls, the theorem holds.