分离链接法 / 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)))
View Code

相关文章: