Collision Resolution: Open Addressing
How Open Addressing Works
In open addressing, all pairs are stored directly in the hash table array (no linked lists). Each slot holds either a pair or is empty (NIL). When a collision occurs at slot , the algorithm probes alternative slots according to a deterministic sequence until an empty slot is found.
The table must have strictly more slots than stored keys: the load factor .
The Probe Sequence
For key , the th probe (starting from ) is:
where is the base hash function and defines the probing strategy. The sequence must be a permutation of so every slot is reachable.
Linear Probing
The simplest strategy: if slot is occupied, try , then , and so on (wrapping around).
Primary clustering: contiguous runs of occupied slots form, and any key hashing anywhere into the run must probe through the entire run. Linear probing effectively reduces the selectivity of the hash function: keys that did not originally collide end up competing for the same slots. Using a step size other than 1 does not solve this (it just shifts where clustering appears).
Quadratic Probing
For example, with : probe sequence (differences ). Starting from different values produces different sequences, so keys that collide under do not follow each other indefinitely.
Secondary clustering: keys that hash to the same value still follow the same probe sequence and collide repeatedly. This is less severe than primary clustering.
Double Hashing
Uses a second independent hash function . To ensure is always coprime to (so the probe sequence visits all slots), a common choice is:
Double hashing approximates the uniform hashing assumption: each probe sequence is equally likely to be any permutation. It avoids both primary and secondary clustering, at the cost of computing a second hash function.
Insert, Search, and Delete
INSERT: start at . Probe . If slot is NIL, insert there. If slot is occupied by a key that equals , update the value. If a full cycle is made without finding an empty slot, the table is full (or the probe sequence was flawed).
SEARCH: start at . Probe . If slot matches the key, return value. If an empty (NIL) slot is reached, the key is not present. If a full cycle completes, key not present.
DELETE: you cannot simply set the slot to NIL, because that would break probe sequences for other keys. A search for a key that probed past the now-deleted slot would falsely terminate at the NIL.
Instead, use a tombstone (deleted marker): when searching, a tombstone means “keep probing” (it is not an empty slot). When inserting, a tombstone counts as “available” (can be overwritten).
Performance
Under the uniform hashing assumption, the expected number of probes for:
- Unsuccessful search:
- Successful search:
Example with : unsuccessful search expects probes; successful search expects probes.
With : unsuccessful expects probes; successful expects probes.
Performance degrades sharply as . Typical implementations rehash when exceeds .
Resizing with Open Addressing
Maintain counters for the number of live keys () and tombstones (). When exceeds a threshold (e.g. ):
- If : rehash into a larger table.
- If : rehash into a table of the same size (purging tombstones).
- If : rehash into a smaller table.
Tables sizes are often chosen as primes to improve hash function behaviour.
Summary
| Probing Method | Probe Sequence | Clustering Issue |
|---|---|---|
| Linear | Primary clustering | |
| Quadratic | Secondary clustering | |
| Double hashing | Negligible | |
| Tombstone | Deleted marker | Enables correct deletion |
| Load factor limit | Typically keep | |
| Expected unsuccessful probes | Under uniform hashing | |
| Expected successful probes | Under uniform hashing |