【发布时间】:2015-02-11 22:19:55
【问题描述】:
我正在学习抽象数据类型here。最近我一直在阅读有关使用 Map(或某些数据结构,如 dict)的散列。
代码如下所示:
class HashTable:
def __init__(self):
self.size = 11
self.slots = [None] * self.size
self.data = [None] * self.size
def put(self,key,data):
hashvalue = self.hashfunction(key,len(self.slots))
if self.slots[hashvalue] == None:
self.slots[hashvalue] = key
self.data[hashvalue] = data
else:
if self.slots[hashvalue] == key:
self.data[hashvalue] = data #replace
else:
nextslot = self.rehash(hashvalue,len(self.slots))
while self.slots[nextslot] != None and \
self.slots[nextslot] != key:
nextslot = self.rehash(nextslot,len(self.slots))
if self.slots[nextslot] == None:
self.slots[nextslot]=key
self.data[nextslot]=data
else:
self.data[nextslot] = data #replace
def hashfunction(self,key,size):
return key%size
def rehash(self,oldhash,size):
return (oldhash+1)%size
def get(self,key):
startslot = self.hashfunction(key,len(self.slots))
data = None
stop = False
found = False
position = startslot
while self.slots[position] != None and \
not found and not stop:
if self.slots[position] == key:
found = True
data = self.data[position]
else:
position=self.rehash(position,len(self.slots))
if position == startslot:
stop = True
return data
def __getitem__(self,key):
return self.get(key)
def __setitem__(self,key,data):
self.put(key,data)
现在在教科书中,作者指出哈希表的大小是任意的。见这里:
请注意,哈希表的初始大小已选择为 11. 虽然这是任意的,但重要的是大小必须是素数,这样冲突解决算法可以如下 尽可能高效。
为什么这是任意的?似乎给定的槽数与可以存储多少值直接相关。我知道其他哈希表可能很灵活并且能够将更多数据存储到一个数据槽中,但在 THIS 特定示例中,它不仅仅是“任意”。就是可以存储多少个值。
我错过了什么吗?
【问题讨论】:
-
我认为这是一种“最小散列”——这是你能做的最少的事情,而且仍然有一些你可以称之为散列函数的东西。显然,您可以通过添加一些代码来扩展它,例如,如果散列已满(或者更有可能,如果负载变得太高)来调整散列的大小。这可能是你尝试的一个很好的练习。
-
它不是关于存储在 HashTable 中的大小,我认为我指的是制作简单的哈希函数。为此使用素数,例如here.
-
感谢您确认这是多么基本。我认为我对哈希表如何工作的基本知识是有限的,因此会让人感到困惑。不过,看起来,制作一个具有更大素数的表将允许您拥有更多可用插槽,并且需要更少的重新哈希,并且在每个插槽中搜索的项目更少(如果您将数据插槽扩展到持有多个值)。一般来说,这些物品会分散得更薄。这不正确吗?
-
@ApathyBear 您似乎对“重新散列”的含义感到困惑。通常,哈希表允许固定的占用率,例如。 G。 2/3或类似的东西。所以,如果你有 e。 G。一个有 11 个槽的哈希表,在调整大小之前它可以包含 7 个值。当具有 7 个值的 11 槽表被指示插入第 8 个值时,它分配一个更大的表(例如具有 19 个槽的表),重新计算每个旧条目的哈希和槽索引,将旧条目从旧表到新表,将一个新条目插入新表,然后释放旧表。 …
-
@ApathyBear ... 这就是所谓的重新散列过程,随着表大小的增长,它会重复多次。
标签: python map hashmap hashtable