1+ """
2+ Open addressing with linear probing.
3+ In order to support deletions, we place a special marker in a table location at
4+ which an item has been deleted, so that we can distinguish between it and a location
5+ that has always been empty
6+
7+ OPPEN ADDRESSING CHALLENGE:
8+ - properly trace the series of probes when collisions occur during an insertion or
9+ search for an item."""
10+ import HashMapBase
11+ class ProbeHashMap (HashMapBase ):
12+ """HashMap implemented with linear probing for collision resolutions"""
13+
14+ _AVAIL = object () #sentinel marks location of previous deletion
15+
16+ def _is_available (self , j ):
17+ """Return true if index j is available in the table"""
18+ return self ._table [j ] is None or self ._table [j ] is ProbeHashMap ._AVAIL
19+
20+ def _find_slot (self , j ,k ):
21+ """search for key k in bucket at index j
22+
23+ Return (success, index) tuple, described as follow:
24+ If match was found, success is True and index denotes its location
25+ If no match found, success is False and index denotes first available slots """
26+
27+ firstAvail = None
28+
29+ while True :
30+ if firstAvail is None :
31+ firstAvail = j #mark this as first available
32+
33+ if self ._table [j ] is None :
34+ return (False , firstAvail ) #search has failed
35+ elif k == self ._table [j ]._key :
36+ return (True , j ) #found a match
37+
38+ j = (j + 1 ) % len (self ._table ) #keep looking cyclically
39+
40+ def _bucket_getitem (self , j ,k ):
41+ found , s = self ._find_slot (j , k ) #find slot at bucket j the key k to retrieve the Item
42+
43+ if not found :
44+ raise KeyError ("Key Error" + repr (k )) #no match found
45+
46+ return self ._table [s ]._value #return the element at position s of the hashtable
47+
48+ def _bucket_setitem (self , j , k , v ):
49+ found , s = self ._find_slot (j ,k ) #find at bucket j the key k
50+
51+ if not found :
52+ self ._table [s ] = self ._Item (k ,v ) #insert new item
53+ self ._n += 1 # increase size
54+ else :
55+ self ._table [s ]._value = v #overwrite existing
56+
57+ def _bucket_delitem (self , j , k ):
58+ found , s = self ._find_slot (j ,k ) # find slot in j with key k to delete
59+
60+ if not found :
61+ raise KeyError ("Key error" + repr (k ))
62+
63+ self ._table [s ] = ProbeHashMap ._AVAIL #mark slot as vacated after deletion
64+
65+ def __iter__ (self ):
66+ for j in range (len (self ._table )): # Scan the entire table
67+ if not self ._is_available (j ):
68+ yield self ._table [j ]._key # yields every key in hashtable when iterating
0 commit comments