与Hashtable& amp; amp;字典

时间:2011-02-07 15:04:57

标签: .net

我最近在几次关于Hashtables的采访中进行了深入研究,并且何时需要覆盖GetHashCode()。讨论一直在深入和深入,直到我全身心投入。

我现在正做一些研究,以涵盖下次准备好的一切。

我找到了这篇我想分享的优秀文章: http://msdn.microsoft.com/en-us/library/ms379571(VS.80).aspx#datastructures20_2_topic5

1)我觉得不太满意的是字典是基于哈希的事实,但列表显然不是。这仅仅意味着在List<>中进行搜索和Array []是线性的,而在字典或散列表中搜索是不变的,因此更快?这就是全部吗?

2)如果我使用类作为字典中的键,我需要根据任何必需的标识字段覆盖该类的GetHashcode()以使实例唯一。但是,仍然可能发生两个ID字段相等并且将生成相同的哈希码?如果这是两个实例与相同哈希码冲突期间发生的情况?

3)如何解决碰撞?我在文章中读到了关于Hashtable和Chaining for the Dictionary的碰撞情况下的rehashing方法。但我仍然不确定它是如何工作的,因为我不是数学天才。 : - \有人可以更好地解释它是如何工作的吗?

非常感谢, 卡瓦

2 个答案:

答案 0 :(得分:4)

1)通常,是的,Dictionary<T>HashSet<T>具有恒定的时间访问权限。在未排序的List<T>或数组中定位项目必须线性完成。通过排序集合,您可以进行二进制搜索,从而获得O(log n)访问时间。

2)如果在.NET中覆盖GetHashCode,则还应覆盖Equals方法。在.NET DictionaryHashSet中,您无法插入相同的项目。在一般情况下,哈希冲突是不可避免的(除非您已经计算出完美的哈希值)。有几种方法可以解决冲突。

3)有关冲突解决的更多信息,请参阅http://en.wikipedia.org/wiki/Hash_table

答案 1 :(得分:1)

哈希表是一种数据结构。可以找到更多信息when looking for more general information

1)列表中的默认搜索是线性的(需要遍历所有元素)。完美的散列(无冲突)允许在最坏的情况下进行恒定的时间查找。更多的碰撞会导致查找速度变慢。

2)当散列大量可能键的随机子集时,哈希冲突几乎是不可避免的。因此,大多数哈希表实现都有一些冲突解决策略来处理此类事件。 .NET的Hashtable实现似乎使用double hashing

3)只要您提供正确的哈希码,这是您不必担心的事情。如有兴趣,请阅读有关哈希表的维基文章,其中介绍了几种技术。

更新: 碰撞处理中Hashtable和Dictionaries的实现有a difference。显然,Hashtable已过时,首选DictionaryHashSet

正如Jim Mischel所提到的,你应该覆盖GetHashCode以及Equals。插入相同的项目是不可能的,但具有相同哈希码的项目将由您选择的集合类型处理。