最近,我正在查看使用链接作为链表的哈希表。我开始使用"链"作为AVL树。 因此,哈希表中的每个桶都将具有很少的AVL树的根指针。维基百科说哈希表的最坏情况是O(n)(http://en.wikipedia.org/wiki/Hash_table)。但是,如果我们使用每个桶"链"作为AVL树,我们可以把它降到O(ln n)。
我错过了什么吗? 据我所知,我们可以用AVL树替换链表。 难道这样的ADT不会比单个AVL树或带有链表链接的哈希表更好吗?
我搜索了互联网,找不到这样的ADT。
答案 0 :(得分:3)
这将直接在您引用的维基百科文章中讨论:
与其他结构分开链接
可以使用支持所需操作的任何其他数据结构来代替列表。例如,通过使用自平衡树,可以将常见哈希表操作(插入,删除,查找)的理论最坏情况时间降低到O(log n)而不是O( N)。然而,如果必须不惜一切代价避免长时间延迟(例如,在实时应用中),或者如果必须防止许多条目散列到相同的时隙(例如,如果必须的话),这种方法仅值得麻烦和额外的存储器成本。人们期望非常不均匀的分发,或者对于网站或其他可公开访问的服务,它们容易受到请求中的恶意密钥分发的影响。)
在Java中,标准HashMap
在桶中使用红黑树,如果桶大小超过常量8;如果桶小于6个条目,它们将被线性化回单链表;显然,现实世界的测试表明,由于这种数据结构的一般复杂性和额外的内存占用(因为树条目应该至少包含2个对其他条目的引用,因为单个链接的条目仅包含一个引用),因此对于较小的桶管理它们会因为树损失而更多,而不是从理论上获得更好的渐近复杂度。
我还要补充一点,为了获得最佳性能,哈希表应该被配置为大多数桶只有一个条目(即它们不是偶数列表,只是单独的条目),略少于应该包含两个条目,偶尔应该只有特殊的桶有3个或更多条目。因此,与简单的链表相比,在树中保存1-3个条目完全没有意义。