最近我正在研究哈希表,并了解基础是
创建一个数组,例如
hashtable ht[4];
哈希密钥
int hash = hash_key(key);
获取索引
int index = hash % 4
设置为哈希表
ht[index] = insert_or_update(value)
我知道存在哈希冲突问题,如果key1
和key2
具有相同的哈希值,则会转到相同的ht[index]
,因此separate chaining
可以解决此问题。
具有相同哈希的密钥转到同一个桶,这些密钥将存储在链表中。
我的问题是,如果散列不同,但模数相同会发生什么?
例如,
hash(key1): 3
hash(key2): 7
hash(key3): 11
hash(key4): 15
所以索引是3,这些具有不同散列和不同密钥的密钥转到同一个桶
我搜索谷歌的一些哈希表实现,似乎他们没有处理这种情况。我是否推翻了?怎么了?
例如,这些实现:
https://gist.github.com/tonious/1377667#file-hash-c-L139
redis的: https://github.com/antirez/redis/blob/unstable/src/dict.c#L488
nginx的: https://github.com/nginx/nginx/blob/master/src/core/ngx_hash.c#L34
他们只是比较密钥是否相等
答案 0 :(得分:1)
如果有两个物体'密钥散列到同一个桶,它并不重要,因为它们具有相同的散列,或者因为它们具有不同的散列但它们都映射(通过模数)到同一个桶。如您所知,由于这些情况之一而发生的冲突通常通过将两个对象放在特定于桶的列表中来处理。
当我们在哈希表中查找对象时,我们正在寻找共享相同密钥的对象。散列/模运算仅用于告诉我们我们应该在哪个桶中查看以查看对象是否存在。一旦我们找到了合适的存储桶,我们仍然需要直接比较任何找到的对象(即存储桶特定列表中的对象)的密钥,以确保我们找到了匹配项。
所以两个具有不同哈希值的对象但是映射到同一个桶的情况与两个具有相同哈希值的对象的工作原理相同:我们只使用桶来查找候选匹配,并依靠密钥本身来确定真正的匹配。