HashTable 或 Dictionary 查找时间

Posted

技术标签:

【中文标题】HashTable 或 Dictionary 查找时间【英文标题】:HashTable or Dictionary lookup time 【发布时间】:2011-04-28 12:49:52 【问题描述】:

只要哈希表或字典具有唯一哈希码,它的查找时间是否总是 O(1)?

如果 HashTable 有 1 亿行,那么查找具有 1 行的东西所花费的时间是否相同?

【问题讨论】:

【参考方案1】:

没有。这在技术上是可行的,但非常很难获得完全相同的开销。哈希表被组织成桶。 Dictionary(和 Hashtable)使用如下表达式计算对象的存储桶编号:

int bucket = key.GetHashCode() % totalNumberOfBuckets;

因此具有不同哈希码的两个对象可以在相同桶中结束。存储桶是一个 List,索引器接下来在该列表中搜索 O(n) 的键,其中 n 是存储桶中的项目数。

Dictionary 动态增加 totalNumberOfBuckets 的值以保持桶搜索的效率。当您在字典中抽取一亿个项目时,将有数千个桶。添加项目时桶为空的可能性非常小。但如果是偶然的话,是的,取回物品需要同样长的时间。

随着项目数量的增加,开销的增加非常缓慢。这称为摊销 O(1)。

【讨论】:

【参考方案2】:

可能会有所帮助:.NET HashTable Vs Dictionary - Can the Dictionary be as fast?

【讨论】:

【参考方案3】:

只要没有与哈希值冲突,就可以。

【讨论】:

【参考方案4】:
var dict = new Dictionary<string, string>();
for (int i = 0; i < 100; i++) 
    dict.Add("" + i, "" + i);

long start = DateTime.Now.Ticks;

string s = dict["10"];

Console.WriteLine(DateTime.Now.Ticks - start);

for (int i = 100; i < 100000; i++) 
    dict.Add("" + i, "" + i);

start = DateTime.Now.Ticks;
s = dict["10000"];
Console.WriteLine(DateTime.Now.Ticks - start);

这两种情况都打印 0。所以看起来答案是肯定的。 [已经调低,所以我会解释得更好]

它似乎是恒定的。但这取决于哈希函数在所有键中给出不同的结果。由于没有哈希函数可以做到这一点,这一切都归结为您提供给字典的数据。所以你必须用你的数据来测试它是否是恒定的。

【讨论】:

这并不意味着什么。另一方面,如果它们导致相同的数字不等于 0,它将... 我怀疑这会打印0,即使查找是 O(n)。

以上是关于HashTable 或 Dictionary 查找时间的主要内容,如果未能解决你的问题,请参考以下文章

C#中哈希表(HashTable)的用法详解以及和Dictionary比较

C#中HashTable用法和Dictionary比较

hashset hastable dictionary concurrentdictionary区别

MSBuild任务中的Hashtable / Dictionary参数

Hashtable、Dictionary 和 KeyValuePair 有啥区别?

C# Hashtable和Dictionary区别