哈希表实现 - 冲突检测的替代方案

时间:2015-09-25 23:47:18

标签: hashtable

除了碰撞检测和在哈希表中抛出LinkedList之外,还有哪些其他方法可以实现哈希表?碰撞检测是实现高效哈希表的唯一方法吗?

2 个答案:

答案 0 :(得分:4)

最终,有限大小的哈希表将发生冲突,至少是任何通常编程的冲突。如果您的密钥是string类型,那么哈希表有一个无限个可能的密钥,但是使用哈希表,您只有有限数量的桶。所以从根本上说,必然会发生碰撞。如果您要实现一个忽略冲突的哈希表,那么您将拥有一个非常奇怪的,不确定的数据结构,它似乎会随机删除元素。

现在,后端使用的数据结构不一定是链表。您可以将其实现为红黑树,并在碰撞中获得log(n)性能。您应该查看文章5 Myths About Hash Tables以及this Stack Overflow question about HashMaps vs Maps

现在,如果您对密钥类型有所了解,请说密钥是2个字符长的字符串,那么只有有限数量的可能密钥,然后您可以继续创建转换密钥的“哈希”函数对于相对小整数,您可以创建一个保证不会发生冲突的查找表。

重要的是要注意,良好实现的哈希表不会受到很多冲突的影响。世界上存在更大的问题,如世界饥饿(甚至如何实现有效的哈希函数),而不是计算机必须每5天在链表中遍历三个节点。

答案 1 :(得分:0)

  

除了碰撞检测和在哈希表中抛出LinkedList之外,还有哪些其他方法可以实现哈希表?

其他方式包括:

  • 从元素发生碰撞的节点链接另一个容器类型,例如平衡二叉树或矢量/数组

  • GCC的哈希表支持std::unordered_ X 使用单个链接的单个值列表,以及一个连续的桶容器迭代器数组到列表中;无论当前的load_factor()

  • 使用开放寻址/封闭散列,当插入/查找/擦除找到它已经散列的存储桶中的另一个密钥时,使用一些算法来查找另一个要查找的存储桶(依此类推,直到它找到密钥,它可以插入的已删除元素,或未使用的存储桶);这种"探测"有许多选项,最简单的是尝试下一个桶方法,另一个是二次1,4,9,16 ......,另一种是使用替代哈希函数。

  • 完美哈希函数(下)

  

碰撞检测是实现高效哈希表的唯一方法吗?

  • 有时可以找到一个不会发生碰撞的perfect hash function,但这通常只适用于非常有限的输入集,无论是由于输入的性质(例如,活人的出生月份和年份只有一千个可能的值的顺序),或者因为编译时知道一小部分(例如编译器的一组200个关键字)。