Algorithm 哈希表v/s树

Algorithm 哈希表v/s树,algorithm,data-structures,hash,tree,hashtable,Algorithm,Data Structures,Hash,Tree,Hashtable,哈希表总是比树快吗?虽然哈希表具有O(1)搜索复杂度,但假设由于设计不当的哈希函数而发生大量冲突,并且如果我们使用链式结构(例如平衡树)处理冲突,则最坏的搜索运行时间为O(logn)。因此,我可以得出结论,对于大数据集或小数据集,即使在最坏的情况下,哈希表也总是比树快?另外,如果我有足够的内存,并且不需要范围搜索,我是否可以始终使用哈希表?使用哈希表,并使用适当的维度初始化它。例如,如果您仅使用半个空格,则碰撞非常少。在最坏的情况下,hast表中的时间为O(n)但是这比现在写太阳爆炸的可能性要小

哈希表总是比树快吗?虽然哈希表具有O(1)搜索复杂度,但假设由于设计不当的哈希函数而发生大量冲突,并且如果我们使用链式结构(例如平衡树)处理冲突,则最坏的搜索运行时间为O(logn)。因此,我可以得出结论,对于大数据集或小数据集,即使在最坏的情况下,哈希表也总是比树快?另外,如果我有足够的内存,并且不需要范围搜索,我是否可以始终使用哈希表?

使用哈希表,并使用适当的维度初始化它。例如,如果您仅使用半个空格,则碰撞非常少。

在最坏的情况下,hast表中的时间为O(n)但是这比现在写太阳爆炸的可能性要小几十亿,所以当使用一个好的散列函数时,你可以安全地假设它在O(1)中工作,除非太阳爆炸。
另一方面,哈希表和树的性能可能因实现、语言和月相而异,因此对这个问题的唯一好答案是“两者都尝试,思考并选择更好的”

哈希表总是比树快吗

不,不总是。这取决于许多因素,例如集合的大小、哈希函数,对于某些哈希表实现,还取决于删除操作的数量

哈希表平均每个操作都是
O(1)
,但情况并非总是如此。在最坏的情况下,它们可能是
O(n)

我现在可以想到一些喜欢树木的原因:

  • 订购很重要。[哈希表不维护顺序,BST按定义排序]
  • 是一个问题-您不能承受可能发生的
    O(n)
    。[这对于实时系统可能至关重要]
  • 这些数据可能与您的散列函数“相似”,并且散列到相同位置的许多元素[冲突]不是不可描述的。[这有时可以通过使用不同的哈希函数来解决]
  • 对于相对较小的集合,哈希表的
    O(1)
    之间的隐藏常量比树的隐藏常量高很多倍,对于较小的集合,使用树可能更快

  • 但是-如果数据量很大,延迟不是问题,冲突也不可预测-哈希表比使用树渐进地好。

    如果由于哈希函数设计不当,会发生很多冲突,如果我们使用链式结构(比如平衡树)处理冲突那么最坏的搜索运行时间是O(n)(而不是O(logn))。因此,即使在最坏的情况下,您也无法得出大数据集或小数据集的结论。哈希表总是比树快。

    我不是专家,但我认为这是情境性的。很多散列函数都很昂贵,对于某些访问模式来说,树是很好的。“总是”是一个非常大的包罗万象的词。您是否有可能编辑此问题,将其简化为更具体的内容,例如特定场景(仅限)?否则,它几乎肯定会被关闭为非建设性的。这里的很多人都提到,最坏的情况是O(N)。如果使用平衡树结构而不是链表来处理冲突,那么它怎么可能是O(n)呢。在像AVL这样的平衡树上进行搜索的最坏情况是O(logn)@avinashah您可以通过使用其他溢出数据结构来减少最坏情况下的搜索情况,但您不能免费获得
    O(lgn)
    search。它是以
    O(lgn)
    insert为代价的,因为您现在正在插入一个树或类似的树,在最坏的情况下,它包含所有元素。在几乎所有的应用程序中,折衷是不值得的。通常情况下,由于缓存的一致性(无论是从主内存还是从磁盘),仔细打包的树可能会比哈希表执行得更好。在这种情况下,不管您有多少数据,哈希表可能不是您的最佳选择,这取决于您如何使用字典结构。什么哈希表?打开寻址哈希表还是“Bucket”哈希表?是否进行增量调整?还是基于线性哈希?散列表的实现太多了!你的答案对其中一些是错误的,所以请准确一点。@MatthieuM.:对于几乎所有的哈希表来说,这些都是传统的缺点,即使使用开放寻址或链接作为“bucket”的简单数组。排序是一个缺点,因为散列不能保证保留顺序。延迟是最坏情况下的一个问题(如果由于某些限制,您无法承受任何
    O(n)
    ops,这是一个问题),类似的哈希值实际上不是一个退步,因为它可以通过选择不同的哈希函数轻松解决,如果我没记错的话,大小问题通常是由于哈希函数开销造成的。你有什么特别的问题?@amit:不,没有(除了点餐……显然)。例如,延迟在这里定义不清。我可以用哈希表(使用增量调整大小)保证O(1)插入,而对于BST,我将有常规的重新平衡操作,所以在最坏的情况下是O(logn)。O(1)但查找无法保证;但是我可以通过使用BST作为bucket结构来获得O(logn)。小型集合同样可以从开放寻址哈希表中获益:每个节点的开销更小,单块分配=>比BST更好的CPU缓存行为!所以并不是所有的注释都适用于所有的实现。@MatthieuM.:好的,我明白你的意思了。事实上,没有什么灵丹妙药,是的,有一些解决“传统”DS(如BST作为bucket)某些问题的方法,确实没有一种方法同样适用于所有的DS,但在为您的设置选择DS时,应该考虑这些问题。