分离链接法 / Separate Chain Hashing
前面完成了一个基本散列表的实现,但是还存在一个问题,当散列表插入元素冲突时,散列表将返回异常,这一问题的解决方式之一为使用链表进行元素的存储,即分离链接法。
Separate Chain Hashing: [0] Header->11->0->110 [1] Header->12->1->111 [2] Header->2->112 [3] Header->14->3->113 [4] Header->15->4->114 [5] Header->16->5 [6] Header->17->6 [7] Header->18->7 [8] Header->19->8 [9] Header->9 [10] Header->10
而在利用链表实现分离链接法时,可选用带表头的链表,插入元素时采用前端插入,每次将新元素插入对应散列位置链表的最前端,因为新插入的元素往往被查找的概率较大,放在前面便于缩短查找时间。
下面利用代码实现散列表的分离链接法,
完整代码
1 from hash_table import HashTable, kmt_hashing 2 from linked_list.linked_list_dummy_header import LinkedListDummyHeader as List 3 4 5 class SeparateChainHashing(HashTable): 6 """ 7 Separate Chain Hashing: 8 [0] Header->11->0->110 9 [1] Header->12->1->111 10 [2] Header->2->112 11 [3] Header->14->3->113 12 [4] Header->15->4->114 13 [5] Header->16->5 14 [6] Header->17->6 15 [7] Header->18->7 16 [8] Header->19->8 17 [9] Header->9 18 [10] Header->10 19 """ 20 def __init__(self, size, fn): 21 self._array = [List() for i in range(size)] 22 self._hashing = fn 23 24 def find(self, item): 25 linked_list = self._array[self._hashing(item)] 26 node = linked_list.header.next 27 while node and node.value != item: 28 node = node.next 29 return node 30 31 def _insert(self, item): 32 """ 33 item 34 | 35 V 36 [n] Header->node_1->node_2->node_3 37 """ 38 if item is None: 39 return 40 linked_list = self._array[self._hashing(item)] 41 node = linked_list.header 42 while node.next: 43 if node.next.value == item: # Element existed 44 return 45 node = node.next 46 linked_list.insert(item, 1) 47 48 def delete(self, item): 49 linked_list = self._array[self._hashing(item)] 50 linked_list.delete(item) 51 52 def show(self): 53 print(self) 54 55 @property 56 def load_factor(self): 57 element_num = sum(x.length-1 for x in self._array) 58 return element_num/self.size 59 60 def make_empty(self): 61 # self._array = [List() for i in range(len(self._array))] 62 for chain in self._array: 63 chain.clear() 64 65 66 def test(h): 67 print('\nShow hash table:') 68 h.insert(110, 111, 112, 113, 114) 69 h.insert(range(20)) 70 h.delete(13) 71 h.show() 72 print('\nLoad factor is:', h.load_factor) 73 print('\nClear hash table:') 74 h.make_empty() 75 h.show() 76 77 if __name__ == '__main__': 78 test(SeparateChainHashing(11, kmt_hashing(11)))