【问题标题】:Collision resolution technique in custom hasmap implementation自定义 hasmap 实现中的冲突解决技术
【发布时间】:2013-04-26 15:25:31
【问题描述】:

这是为了采访。 他们问我什么是实现自定义哈希图的好方法。

我的回答是,如果你有一个 say , n 元素数组。

您可以将单个键映射到索引 %n 的整数。 这将使您可以将密钥存储在哈希图中。但 如果发生冲突,那么您可以在自定义数组中保留一个值列表。 现在,像这样在自定义 hashmap 中使用列表的最坏情况是 O(n)。 所以,我建议,我们可以在列表中使用堆(最小堆)并调用 heapify() 来平衡它。这也会给 logn 复杂性?

我想到的另一件事是,我可以使用具有 2-3-4 个节点的树,从而降低登录复杂性。 (有点像 B+ 树)

在自定义堆实现的情况下,有什么更好的办法来解决冲突?

【问题讨论】:

  • 堆在最坏的情况下需要 O(n),因为您可能必须遍历整个堆,直到找到所需的元素。堆不提供通用的查找算法。树建议将约束键以某种方式排序,并且排序必须与散列函数和相等关系一致。

标签: data-structures hashmap


【解决方案1】:

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

虽然复制可能很昂贵,但其成本可能是 amortized 在查找上。

【讨论】:

    【解决方案2】:

    最常见的解决方法是:

    1. deque(PHP 是如何做到的)
    2. 链表
    3. 实际上,只需递增散列值,直到找到不冲突的插槽。

    对于第一个示例,要使用值“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处的双端队列元素中:

    hash_map[hash_key].push_back(myvalue);
    

    hash_map 是你的双端队列的 N 索引数组,myvalue 是要插入的对象(注意 myvalue 应该有自己的 key 成员设置为“hello”,以便稍后检索)。

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

    在发生冲突之前,您几乎会用完存储项目的内存,并且线性搜索的缓慢成为一个限制因素。

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

    【讨论】:

    • 如果 N = 2^32,你需要那么多指针来表示一个空的哈希表。在 x86-64 上是 32GB。
    • 我的假设是(我没有为它编写代码,因为我很懒)你只在第一次引用它们时创建双端队列,并且你创建 hash_map 作为双端队列本身或一个 int ** (数组数组),您可以在其中根据需要为哈希指针实例化页面,或者更聪明的东西。我将把这个练习留给真正想要编写代码的人。即使 N = 2^16(x86-64 上只有 500KB 的内存空间)仍然会产生 1/65536 个项目的分布,因此每 1,000,000 个散列项目的深度约为 15 个项目/deque。 O(M) 其中 M = 15 非常小:)
    猜你喜欢
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    • 2014-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-05
    • 1970-01-01
    相关资源
    最近更新 更多