哈希表v自我平衡搜索树

时间:2010-07-16 13:25:47

标签: hashtable red-black-tree

我很想知道使用自平衡树技术来存储项目的原因是什么,而不是使用哈希表。

我看到哈希表无法维护插入顺序,但我总是可以在顶部使用链表来存储插入顺序。

我看到,对于少量的值,哈希函数会增加成本,但我总是可以将哈希函数与密钥一起保存,以便更快地查找。

我知道散列表很难实现,而不是红黑树的直接实现,但在实际实现中,不会有人愿意为这个问题付出额外的努力吗?

我看到使用哈希表发生冲突是正常的,但是使用双重哈希等开放寻址技术可以将密钥保存在哈希表本身中,这个问题没有减少到不是对这种实施倾向于对红黑树的青睐?

我很好奇,如果我严格地忽略哈希表的缺点,仍然会使红黑树在实际应用中变得非常可行(如文件系统等)。

6 个答案:

答案 0 :(得分:17)

这是我能想到的:

  1. 有多种数据无法散列(或者散列太贵),因此无法存储在散列表中。
  2. 树以您需要(排序)的顺序保存数据,而不是按顺序排列。即使您通过它运行链表,也无法(有效地)使用哈希表执行此操作。
  3. 树木具有更好的最坏情况表现

答案 1 :(得分:5)

存储分配是另一个考虑因素。每次在散列表中填充所有桶时,都需要分配新存储并重新散列所有内容。如果您提前知道数据的大小,则可以避免这种情况。另一方面,平衡树根本不会受到这个问题的影响。

答案 2 :(得分:2)

只想添加:

  • 平衡二叉树具有可预测的获取数据[log n]的时间,与数据类型无关。很多时候,对于您的应用程序估计应用程序的响应时间可能很重要。 [哈希表可能有不可预测的响应时间]。请记住,对于较小的n,就像在大多数常见用例中一样,内存查找中的性能差异并不重要,系统的瓶颈将会出现在其他地方,有时您只是想让系统更加简单。调试和分析。

  • 与哈希表相比,树通常具有更高的内存效率,并且在不对输入键的分布和可能的冲突等进行任何分析的情况下实现起来更加简单。

答案 3 :(得分:1)

在我看来,自平衡树作为学术主题非常有效。和我 不知道什么可以被认定为“直接实现的 红黑树“

在现实世界中,记忆墙使它们的效率远远低于它们在纸上的效率。

考虑到这一点,哈希表是不错的选择,特别是如果你不练习 他们的学术风格(忘记表格大小约束,你神奇地解决 表重新调整问题和几乎所有碰撞问题。)

总之一句:保持简单。如果这对您来说很简单,那么这对您的计算机来说很简单。

答案 4 :(得分:1)

我能想到的几个原因:

  1. 树是动态的(空间复杂度是N),而哈希表通常实现为固定大小的数组,这意味着它们通常用K大小初始化,其中K> 1。 N,所以即使你在hashmap中只有1个元素,你仍然可能有100个占用内存的空插槽。这样做的另一个影响是:

  2. 增加基于数组的哈希表的大小是昂贵的(O(N)平均时间,O(N log N)最差情况),而树可以在恒定时间内增长(O(1))+ (定位插入点的时间(O(log N))

  3. 树中的元素可以按排序顺序收集(使用ex:in-order-traversal)。因此,您经常会将排序列表作为带树的免费特权。
  4. 根据hashmap的实现方式,树可以具有比hashmap更好的最坏情况性能(例如:带链接的hashmap将具有O(N)最坏情况,而自平衡树可以保证O(log N)最差适用于所有业务的案例)。
  5. 在最坏的情况下(假设hashmap确实处理了分裂),自平衡树和散列图都具有最差情况下的O(log N)效率,但是Hashmaps可以具有更好的平均情况性能(通常接近O(1)),而树将有一个常数O(log N)。这是因为即使你的hashmap可以在O(1)中找到插入索引,它也必须考虑散列分裂(多个元素散列到同一个数组索引),因此在最好的情况下降级为自平衡树(例如hashmap的Java实现),也就是说,hashmap中的每个元素都可以实现为自平衡树,存储散列到给定数组单元的所有元素。

答案 5 :(得分:0)

我认为如果你想查询一系列键而不是一个键,自平衡树结构将比哈希表结构表现更好。