我在学校,我们一直在学习哈希。对于开放寻址,我们已经了解了三种探测方法:线性探测,二次探测和双重散列。
在这里的类似问题上,Jim Mischel回答说: “[...]你还应该注意到,在实践中,只要负载系数合理并且你具有良好的散列函数,这些(线性,二次,双重散列)的性能几乎没有真正的差别,其他开放式寻址方案,如cuckoo哈希等。“
据我所知,Java的HashMap是使用链接列表单独链接实现的。 人们使用线性/二次探测编写自己的实现是否常见,而不是使用Java的默认实现?考虑到Jim所说的,如果人们仍然使用双哈希而不是线性/二次探测他们想要开放式解决?
答案 0 :(得分:1)
据我所知,Java的HashMap是使用链接列表单独链接实现的。
这是对的。但是,Java有another hash map implementation * ,称为IdentityHashMap<K,V>
,它使用线性探测:
实施说明:这是一个简单的线性探测哈希表,如Sedgewick和Knuth的文章中所述。阵列交替显示保持键和值。 (对于大型表,这比使用单独的数组具有更好的局部性。)对于许多JRE实现和操作混合,此类将产生比HashMap更好的性能(HashMap使用链接而不是线性探测)。
我不知道具有二次探测的哈希表的框架实现。对我来说,在我自己的实现中进行二次探测的最明显的原因是当彼此相邻的散列桶用数据填充时避免“散列簇”,而桶阵列的其他连续区域保持为空。但最终,这是对原始对象上不太理想的哈希函数的补偿,因为理论上不应该发生聚类。
* 严格地说,IdentityHashMap
不是哈希映射的正确实现,因为它通过使用身份而不是相等比较来打破契约。