自定义hasmap实现中的碰撞解决技术

时间:2013-04-26 15:25:31

标签: data-structures hashmap

这是面试。 他们问我,实现自定义hashmap的好方法是什么。

我回答说,如果你有一系列说,n,元素。

您可以将单个键映射到索引%n的整数。 这将允许您将密钥存储在hashmap中。但 如果存在冲突,则可以在自定义数组中保留值列表。 现在,在自定义散列映射中使用列表的最坏情况是O(n)。 所以,我建议,我们可以在列表中使用Heap(min-heap)并调用heapify() 平衡它。这也会给登录复杂性?

我想到的另一件事是,我可以使用2-3-4节点的树,因此登录复杂性会降低。 (像B +树那样的东西)

在自定义堆实现的情况下解决冲突的更好的想法是什么?

2 个答案:

答案 0 :(得分:1)

最常见的是通过以下方式解决hashmap冲突:

  1. deque(PHP如何做到)
  2. 链表
  3. 实际上,只需增加散列值,直到找到一个非冲突的插槽。
  4. 对于第一个示例,要使用值“world”存储键“hello”,您将通过哈希函数获取整数hashmap键(假设C / C ++实现):

    // the following is given: that there is some object "myvalue"
    // where myvalue.value = "world", and myvalue.key = "hello".
    int hash_key = hash(myvalue.key); //myvalue.key = "hello", as given
    

    然后将值插入索引hash_key的deque元素:

    hash_map[hash_key].push_back(myvalue);
    

    其中hash_map是您的N-index deques数组,myvalue是要插入的对象(请注意myvalue应将其自己的key成员设置为“你好“所以以后可以检索。”

    要在哈希映射中查找项目,请对键(“hello”)进行哈希处理,然后遍历双端队列,直到找到该项目。如果散列函数的摘要空间足够大(例如,32位无符号整数= 40亿个唯一散列结果)并且散列函数给出均匀分布,那么碰撞的几率就足够小(1 in 2 ^ 32)你的双端队列可能只有1或2个项目(即使你正在存储2 ^ 33个项目),而且更高级的结构(AVL树,RB树,等等)会使数据结构比它有所帮助减慢速度。

    在碰撞之前,你几乎绝对会耗尽内存存储项目,而线性搜索的缓慢会成为一个限制因素。

    (编辑添加:您不必[也不应该,对于大型哈希函数空间]预先分配整个哈希映射。也请使用deque,以便它随着数量的增长而增长哈希结果增长。)

答案 1 :(得分:1)

通常的技巧(至少,这就是Python和Java都这样做)是通过将动态数组或链接列表放在散列桶中来解决冲突,正如您所建议的那样。此外,哈希表获得一个名为最大负载因子的参数,例如, 2/3。当负载因子高于其允许的最大值(表超过2/3满)时,new hash table is allocated比原始数据大两倍,并且所有数据都被移入新哈希值表

虽然复制可能很昂贵,但其成本可能比amortized更高。