散列表 / Hash Table
散列表与散列函数
散列表是一种将关键字映射到特定数组位置的一种数据结构,而将关键字映射到0至TableSize-1过程的函数,即为散列函数。
Hash Table: [0] -> A [1] -> B [2] -> C [3] -> D [4] -> E
下面以一个简单的散列函数 Hash(Key)=Key mod TableSize为例,完成一个散列表的实现。
Note: 为方便起见,这里选用了一个非素数作为TableSize,适宜的TableSize应为一个素数。
完整代码
1 from collections import Iterable 2 3 4 class CollisionError(Exception): 5 pass 6 7 8 class HashTable: 9 """ 10 Hash Table: 11 [0] -> A 12 [1] -> B 13 [2] -> C 14 [3] -> D 15 [4] -> E 16 """ 17 def __init__(self, size, fn): 18 self._array = [None for i in range(size)] 19 self._hashing = fn 20 21 def __str__(self): 22 return '\n'.join('[%d] %s' % (index, item) for index, item in enumerate(self._array)) 23 24 def find(self, item): 25 hash_code = self._hashing(item) 26 value = self._array[hash_code] 27 return value if value == item else None, hash_code 28 29 def insert(self, *args): 30 for i in args: 31 if isinstance(i, Iterable): 32 for j in i: 33 self._insert(j) 34 else: 35 self._insert(i) 36 37 def _insert(self, item): 38 if item is None: 39 return 40 hash_code = self._hashing(item) 41 value = self._array[hash_code] 42 if value is not None and value != item: # Handle value 0 and value existed situation. 43 raise CollisionError('Hashing value collided!') 44 self._array[hash_code] = item 45 46 def delete(self, item): 47 hash_code = self._hashing(item) 48 if self._array[hash_code] != item: 49 raise KeyError('Key error with %s' % item) 50 self._array[hash_code] = None 51 52 def show(self): 53 print(self) 54 55 @property 56 def size(self): 57 return len(self._array) 58 59 @property 60 def load_factor(self): 61 element_num = sum(map(lambda x: 0 if x is None else 1, self._array)) 62 return element_num/self.size 63 64 def make_empty(self): 65 self._array = [None for i in range(self.size)] 66 67 68 def kmt_hashing(size): 69 # Key = Key mod TableSize 70 return lambda x: x % size 71 72 73 def test(h): 74 print('\nShow hash table:') 75 h.show() 76 77 print('\nInsert values:') 78 h.insert(7, 8, 9) 79 h.insert(range(7)) 80 h.show() 81 print('\nInsert values (existed):') 82 h.insert(1) 83 h.show() 84 print('\nInsert value (collided):') 85 try: 86 h.insert(11) 87 except CollisionError as e: 88 print(e) 89 90 print('\nFind value:') 91 print(h.find(7)) 92 print('\nFind value (not existed):') 93 print(h.find(77)) 94 95 print('\nDelete value:') 96 h.delete(7) 97 h.show() 98 print('\nDelete value (not existed):') 99 try: 100 h.delete(111) 101 except KeyError as e: 102 print(e) 103 104 print('\nLoad factor is:', h.load_factor) 105 print('\nClear hash table:') 106 h.make_empty() 107 h.show() 108 109 if __name__ == '__main__': 110 test(HashTable(10, kmt_hashing(10)))