peo*_*oro 48 language-agnostic algorithm tree hash data-structures
当我需要在哈希表或平衡二叉树之间进行选择以实现集合或关联数组时,我应该考虑哪些因素?
Mat*_* M. 52
这个问题无法回答,总的来说,我担心.
问题是有很多类型的哈希表和平衡二叉树,它们的性能差别很大.
所以,天真的答案是:它取决于你需要的功能.如果您不需要排序则使用哈希表,否则使用平衡二叉树.
有关更详细的答案,让我们考虑一些替代方案.
哈希表(参见维基百科的一些基础知识)
二叉树
我们不要忘记O(1)是渐近的复杂性.对于少数元素,系数通常更重要(性能方面).如果您的哈希函数很慢,则尤其如此...
最后,对于集合,您可能还希望考虑概率数据结构,例如布隆过滤器.
sup*_*cat 41
如果不需要以任何顺序保存数据,散列表通常会更好.如果必须对数据进行排序,则二叉树会更好.
I G*_*ERS 11
现代架构上值得注意的一点:如果Hash表的加载因子较低,则通常会比二叉树具有更少的内存读取.由于与烧录CPU周期相比,内存访问往往相当昂贵,因此哈希表通常更快.
在下面的二进制树中,假设是自平衡的,如红黑树,AVL树或类似treap.
另一方面,如果您在决定扩展时需要重新散列哈希表中的所有内容,这可能是一个代价高昂的操作(摊销).二叉树没有这个限制.
二进制树在纯函数语言中更容易实现.
二叉树具有自然的排序顺序和自然的方式来遍历所有元素的树.
当哈希表中的加载因子很低时,可能会浪费大量内存空间,但是有两个指针,二叉树往往会占用更多空间.
哈希表几乎是O(1)(取决于你如何处理负载因子)与Bin树O(lg n).
树木往往是"平均表现者".他们没有什么特别好的,但是他们没有做什么特别糟糕的事情.
二叉搜索树需要密钥之间的总顺序关系.哈希表仅需要具有一致哈希函数的等价或身份关系.
如果总订单关系可用,则排序数组具有与二叉树相当的查找性能,以哈希表的顺序排列的最坏情况插入性能,以及比两者更少的复杂性和内存使用.
如果将最坏情况的查找复杂度增加到O是可接受的,那么散列表的最坏情况插入复杂度可以留在O(1)/ O(log K)(K具有相同散列的元素的数量). K)或O(log K)如果可以对元素进行排序.
如果密钥更改,则树和散列表的不变量都很难恢复,但对于排序的数组,要小于O(n log N).
这些是在决定使用哪种实施时要考虑的因素:
哈希表是更快的查找:
二叉树: