【问题标题】:Why std::map is red black tree and not hash table ?为什么 std::map 是红黑树而不是哈希表?
【发布时间】:2014-05-05 03:28:28
【问题描述】:

这对我来说很奇怪,我以为它是一个哈希表。

我在以下答案中看到了 3 个原因(这可能是正确的,但我认为它们不是真正的原因)。 Hash tables v self-balancing search trees

  1. 虽然哈希可能不是一个简单的操作。我认为对于大多数类型来说它都非常简单。

  2. 当您使用 map 时,您会期望某些东西会为您提供分期 O(1) 的插入、删除、查找,而不是 log(n)。

  3. 我同意树在最坏情况下的性能更好。

我认为有一个更大的原因,但我无法弄清楚。 在 c# 中,例如 Dictionary 是一个哈希表。

【问题讨论】:

  • 内存曾经非常昂贵。使用std::unordered_map实现map的哈希表。
  • 红黑树也有顺序。

标签: c++ std


【解决方案1】:

这在很大程度上是一个历史事故。标准容器(连同迭代器和算法)是在标准特性集被冻结之前最后添加的内容之一。碰巧的是,他们当时没有他们认为的基于哈希的地图的充分定义,并且在冻结特征之前没有时间添加它,因此原始规范仅包含基于树的地图.

C++ 11 添加了std::unordered_map(以及std::unordered_setmulti 两者的版本),尽管它基于散列。

【讨论】:

  • 在标准化之前,标准容器肯定已经在 STL 中工作了多年。很难看出“没有时间添加它”。诚然,这个问题才成为 STL 具有此属性的原因之一,这使我们无法找到答案。
  • @LightnessRacesinOrbit:他们一直在努力,但请记住,(以整数计算)只有大约一半的 STL 被接受为标准。尤其是在实际规范方面,似乎有相当多的内容几乎没有及时被写入标准中。
【解决方案2】:

原因是map 被显式调用为有序容器。它使元素保持排序,并允许您在线性时间内按排序顺序进行迭代。哈希表无法满足这些要求。

在 C++11 中,他们添加了 std::unordered_map,这是一个哈希表实现。

【讨论】:

  • 不要侮辱,但我真的不明白为什么这会被投票。我将问题解读为:“为什么标准要求订购地图?”这回答:“因为标准要求订购地图。”确实如此,但这没有告诉为什么
  • @Jerry Coffin 我读到(并回答)了“为什么map 的实现不是哈希表”的问题。也许 OP 会澄清他们的实际问题。
  • 问题澄清肯定会有所帮助。我也不明白 OP 到底在寻求什么帮助。
  • @MarkB:是的——基本问题是标准没有强制使用红黑树(或根本没有树)。有不使用红黑树的地图实现。
  • @Jerry Coffin 仅供参考,什么非树容器满足map 的复杂性要求? (我们同意它不要求使用红黑树)
【解决方案3】:

哈希表需要一个额外的哈希函数。使用树的map 的当前实现可以通过使用operator< 在没有额外哈希函数的情况下工作。此外,地图允许对元素进行排序访问,这对某些应用程序可能是有益的。使用 C++,我们现在可以使用 unordered_set 形式的哈希版本。

【讨论】:

  • 复制构造函数和赋值运算符=,以及<== 运算符应该为存储在容器中的元素(例如map、vector、列表、双端队列等)。因此,完全支持复制和比较。
  • @cplusplus ooa and d 你有这方面的参考吗?我从未听说过 == 是任何容器的要求。
  • @MatthiasB:我有理由确定它不是任何容器的要求(尽管它被一些算法使用,例如std::find)。需要比较相等性的容器使用<: (!a
  • @GWW std::map 直接使用 operator<,有两个间接作用:I) std::map<K, V> 只是 std::map<K, V, std::less<K>> 的简写II)std::less 的默认实现使用operator<。因此,您可以将 std::less<X> 专门用于特定类型 X 以使用 operator< 以外的其他内容,或者(更实际地)您可以使用不同的比较器显式参数化映射,例如 std::map<K, V, std::greater<K>> 以降序存储键订购。
  • @CPlusPlusOOAandD:我几乎可以预测结果:拥有/缺少== 没有任何区别。没有定义 < 的类型根本不会编译,除非您在(尝试)实例化地图时还为比较指定一些内容。
【解决方案4】:

简单的答案:因为哈希表无法满足在std::map 上迭代的复杂性要求。

为什么std::map 有这些要求?无法回答的问题。历史因素有所贡献,但总的来说,就是这样

哈希值以std::unordered_map 的形式提供。

这两者叫什么或者用其他语言叫什么并不重要。

【讨论】:

    猜你喜欢
    • 2012-01-06
    • 2023-03-14
    • 2011-04-11
    • 2018-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-13
    • 1970-01-01
    相关资源
    最近更新 更多