如何用链接实现哈希表?

时间:2011-04-09 05:06:11

标签: hashtable ocaml chaining

这可能是一个愚蠢的问题但是,我不能因为上帝之爱在链接哈希表背后的理论中找出我所缺少的东西。

这就是我的理解:

哈希表使用哈希将密钥与存储值的位置相关联。有时哈希将为不同的密钥产生相同的位置,即可能发生冲突。

在这种情况下,我们可以通过将具有相同位置的所有值存储到该位置的链接列表来实现链接。

我不明白的是:

当您输入密钥并且哈希函数产生链接的位置时,它如何确定该位置的链表中的哪个值属于该特定键,而不是碰撞中涉及的另一个键?

我意识到这是基本理论,但是如果有人能够在我的推理中指出错误或告诉我我缺少什么,我将非常感激。

2 个答案:

答案 0 :(得分:4)

简单方法:维护“哈希表条目”的链表,这是键/值对。进入存储桶后,请检查存储桶中所有密钥的查询密钥。

答案 1 :(得分:0)

  

当您输入密钥并且哈希函数产生链接的位置时,它如何确定该位置的链表中的哪个值属于该特定键,而不是碰撞中涉及的另一个键?

您只需按键线性搜索存储桶即可。

您可能会欣赏以F#编写的以下迷你哈希表实现,取自this blog post

> let hashtbl xs =
    let spine = [|for _ in xs -> ResizeArray()|]
    let f k = spine.[k.GetHashCode() % spine.Length]
    Seq.iter (fun (k, v) -> (f k).Add (k, v)) xs
    fun k -> Seq.pick (fun (k', v) -> if k=k' then Some v else None) (f k);;
val hashtbl : seq<'a * 'b> -> ('a -> 'b) when 'a : equality

hashtbl函数采用键值对的关联序列xs,构建表示为spineResizeArray数组的哈希表并返回lambda函数找到适当的存储桶并在其中对给定的密钥k进行线性搜索。线性搜索使用Seq.pick函数执行。