Open addressing: the colliding item is placed in a different cell of the table, each table cell inspected is referred to as a “probe”. Colliding items lump together, causing future collisions to cause a longer sequence of probes. There are three different ways we can handle this:
Linear Probing
Linear Probing: handles collisions by placing the colliding item in the next (circularly) available table cell. If we try to insert a key into a cell that is already occupied, we try again at (and repeat until we find an empty cell to insert into).
In order to
get(k):- We start at cell
- Probe consecutive locations until one of the following occurs:
- item with key is found
- empty cell is found
- cells have been unsuccessfully probed
Example pseudo-code:
def get(k): i = h(k) p = 0 repeat: c = A[i] if c == null: return null else if c.getKey() == k: return c.getValue() else: i = (i + 1) mod N p += 1 until p == N return nullIn order to
remove(k):- search for an entry with key
- if such an entry is found, replace it with special item “available” and we return element
- else, return
In order to
put(k,v):- throw an exception if the table is full
- start at cell
- probe consecutive cells until:
- a cell is found that is either empty or stores “available”
- or until cells have been unsuccessfully probed
- we store in cell
Double Hashing
Double Hashing: we use a secondary hash function . If maps some key to a cell with , that is already occupied, then we iteratively try the buckets:
Where .
The secondary hash function cannot have zero values. The table size must be prime to allow probing of all of the cells.
A common choice of compression function for the secondary hash function:
Where and is prime.
Link to original- Quadratic Hashing: (not incl., p.396, individual study)