@@ -28,7 +28,7 @@ def __iter__(self):
28
28
29
29
30
30
class Slot (object ):
31
- """定义一个 hash 表 数组的槽
31
+ """定义一个 hash 表数组的槽(slot 这里指的就是数组的一个位置)
32
32
注意,一个槽有三种状态,看你能否想明白。相比链接法解决冲突,二次探查法删除一个 key 的操作稍微复杂。
33
33
1.从未使用 HashMap.UNUSED。此槽没有被使用和冲突过,查找时只要找到 UNUSED 就不用再继续探查了
34
34
2.使用过但是 remove 了,此时是 HashMap.EMPTY,该探查点后边的元素扔可能是有key
@@ -60,10 +60,15 @@ def _hash(self, key):
60
60
return abs (hash (key )) % len (self ._table )
61
61
62
62
def _find_key (self , key ):
63
+ """
64
+ 解释一个 slot 为 UNUSED 和 EMPTY 的区别
65
+ 因为使用的是二次探查的方式,假如有两个元素 A,B 冲突了,首先A hash 得到是 slot 下标5,A 放到了第5个槽,之后插入 B 因为冲突了,所以继续根据二次探查方式放到了 slot8。
66
+ 然后删除 A,槽 5 被置为 EMPTY。然后我去查找 B,第一次 hash 得到的是 槽5,但是这个时候我还是需要第二次计算 hash 才能找到 B。但是如果槽是 UNUSED 我就不用继续找了,我认为 B 就是不存在的元素。这个就是 UNUSED 和 EMPTY 的区别。
67
+ """
63
68
index = self ._hash (key )
64
69
_len = len (self ._table )
65
70
while self ._table [index ] is not HashTable .UNUSED :
66
- if self ._table [index ] is HashTable .EMPTY :
71
+ if self ._table [index ] is HashTable .EMPTY : # 注意如果是 EMPTY,继续寻找下一个槽
67
72
index = (index * 5 + 1 ) % _len
68
73
continue
69
74
elif self ._table [index ].key == key :
@@ -75,7 +80,7 @@ def _find_key(self, key):
75
80
def _find_slot_for_insert (self , key ):
76
81
index = self ._hash (key )
77
82
_len = len (self ._table )
78
- while not self ._slot_can_insert (index ):
83
+ while not self ._slot_can_insert (index ): # 直到找到一个可以用的槽
79
84
index = (index * 5 + 1 ) % _len
80
85
return index
81
86
0 commit comments