【发布时间】:2011-11-18 16:11:49
【问题描述】:
众所周知,解决冲突有 2 种经典策略:分离链接和开放寻址。
我想知道为 .net 中的 HashTable/Dictionary 选择了哪一个。
还是使用了其他策略?
【问题讨论】:
-
好问题。如果你没有发布这个问题,我可能永远不会查阅那篇论文。
标签: c# .net hashtable collision
众所周知,解决冲突有 2 种经典策略:分离链接和开放寻址。
我想知道为 .net 中的 HashTable/Dictionary 选择了哪一个。
还是使用了其他策略?
【问题讨论】:
标签: c# .net hashtable collision
在 MSDN 上的这篇论文中都有描述:An Extensive Examination of Data Structures Using C# 2.0
...称为 rehasing 的冲突解决技术,它是 .NET Framework 的 Hashtable 类使用的技术。在决赛中 部分,我们将查看使用碰撞的 Dictionary 类 解析技术称为链接。 ....
... Rehasing 的工作原理如下:有一组不同的哈希 函数,H1 ... Hn,以及在从 哈希表,最初使用 H1 哈希函数。如果这导致 如果发生碰撞,则尝试使用 H2,并在需要时尝试直至 Hn。 上一节只展示了一个哈希函数,即 初始哈希函数(H1)。其他哈希函数非常相似 到这个函数,只用一个乘法因子来区分。在 一般来说,散列函数Hk定义为:
Hk(key) = [GetHash(key) + k * (1 + (((GetHash(key) >> 5) + 1) % (hashsize – 1)))] % hashsize
Dictionary 类在更多方面与 Hashtable 类不同 比一个。除了是强类型的,字典还 采用与 Hashtable 不同的冲突解决策略 类,使用称为链接的技术。回想一下 探测,如果发生冲突,列表中的另一个插槽 桶被尝试。 (通过重新散列,散列被重新计算,并且 尝试了新的插槽。)但是,使用链接,辅助数据结构 用于保持任何碰撞。具体来说,每个插槽 Dictionary 有一个映射到该存储桶的元素数组。在里面 发生碰撞时,碰撞元素被添加到 存储桶列表。
记住只有第一句话是我自己的:-)
【讨论】:
Dictionary 没有二级数据结构来保存冲突。至少在 C# 4 中没有。
Dictionary<K,V> 的非常准确的描述。我的理解是每个桶都包含一个元素的链表(如果没有冲突,链表将包含一个元素)。
Dictionary 最近到底做了什么。
这实际上是一个非常有趣的问题;我刚刚完成了blog post 关于Dictionary 是如何在幕后实现的。我可能会在以后的文章中介绍Hashtable。
【讨论】: