【问题标题】:Time Complexity of Hash Tables in CC中哈希表的时间复杂度
【发布时间】:2013-03-14 06:57:22
【问题描述】:

我对哈希表的概念还很陌生,我一直在阅读不同类型的哈希表查找和插入技术。

我想知道线性探测、链接和二次探测的时间复杂度有什么区别?

我主要对哈希表中节点的插入、删除和查找感兴趣。因此,如果我将每个进程的系统时间(插入/搜索/删除进程)与进程号绘制成图表,那么图表会有什么不同呢?

我猜: - 二次探测将是最坏情况 O(nlogn) 或 O(logn) 进行搜索 - 线性探测将是搜索的最坏情况 O(n) - 不确定,但我认为 O(n^2) 用于链接

有人可以证实这一点吗?谢谢!

【问题讨论】:

标签: c data-structures hashtable big-o


【解决方案1】:

实际上令人惊讶地由于各种原因,很难准确地分析所有这些不同的哈希方案。首先,除非你对你的散列函数做出非常强的假设,否则很难准确地分析这些散列方案的行为,因为不同类型的散列函数会导致不同的性能。其次,与处理器缓存的交互意味着某些类型的哈希表在理论上稍差,实际上可以胜过理论上稍好一些的哈希表,因为它们的访问模式更好。

如果您假设您的哈希函数看起来像一个真正的随机函数,并且如果您将哈希表中的负载因子最多保持为常数,那么所有这些哈希方案都需要 O(1) 的查找时间。换句话说,每个方案,按照预期,只需要您执行恒定数量的查找即可找到任何特定元素。

理论上,线性探测比二次散列和链式散列要差一些,因为除非散列函数具有强大的理论特性,否则元素往往会聚集在一起。然而,在实践中,由于引用的局部性,它可能非常快:所有查找往往彼此接近,因此发生的缓存未命中率较低。二次探测具有较少的碰撞,但没有那么好的局部性。链式散列往往很少有冲突,但往往具有较差的引用局部性,因为链式元素通常不是连续存储的。

在最坏的情况下,所有这些数据结构都可能需要 O(n) 时间来进行查找。这种情况发生的可能性极小。在线性探测中,这将要求所有元素连续存储而没有间隙,并且您必须查找第一个元素。使用二次散列,您必须拥有一组看起来非常奇怪的桶才能获得这种行为。使用链式散列,您的散列函数必须将每个元素转储到同一个桶中,以获得绝对最坏情况的行为。所有这些都不太可能发生。

简而言之,如果您选择其中任何一种数据结构,除非您的哈希函数非常糟糕,否则您不太可能被严重烧毁。我建议使用链式散列作为默认值,因为它具有良好的性能并且不会经常遇到最坏情况的行为。如果你知道你有一个很好的哈希函数,或者有一个小的哈希表,那么线性探测可能是一个不错的选择。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 2020-11-19
    • 2011-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    • 2014-01-02
    • 2015-10-11
    • 2018-09-14
    相关资源
    最近更新 更多