【问题标题】:Time complexity of find() in std::map?std::map 中 find() 的时间复杂度?
【发布时间】:2012-04-15 05:54:52
【问题描述】:

std::map 类的 find() 函数效率如何?它是遍历所有元素以寻找 O(n) 的键,还是在平衡树中,或者它使用散列函数还是什么?

【问题讨论】:

标签: c++ map complexity-theory std


【解决方案1】:

Log(n)基于红黑树。

编辑:n 当然是地图中的成员数。

【讨论】:

  • 虽然这在一定程度上是正确的,但在较大的地图中存在限制。如果您正在查看非常大的数据集,我建议您同时查看替代关联数组容器。
  • 确实是 log(n)。不正确,它基于红/黑树。该标准将操作定义为具有 log(n) 的最大复杂度,实现这一点的最有效方法是使用红/黑树(尽管这不是必需的)。因此,您本末倒置。
  • @OrgnlDave:是的。标准保证它。我认为您不了解复杂性是什么(您的陈述可能适用于绝对速度,但不适用于复杂性)。而且 100MB 在现代机器上仍然很小,您不太可能真正测量出差异。
  • @OrgnlDave:它没有。
  • @std''OrgnlDave:我认为你应该阅读this wikipedia pagestd::map::find 绝对是 log(n)。您提到缓存和“现实世界的约束”这一事实告诉我们您对大 O 表示法有误解。你认为std::map::find 有什么复杂性?
【解决方案2】:

std::mapstd::set 由编译器供应商使用高度平衡的二叉搜索树(例如红黑树、AVL 树)实现。

正如 David 正确指出的那样,find 需要 O(log n) 时间,其中 n 是容器中元素的数量。

但这是针对原始数据类型,例如 intlongchardouble 等,而不是字符串。

如果std:string,假设大小为“m”,用作键,遍历平衡二叉搜索树的高度将需要给定键的 log n 比较与条目树。

std::stringstd::mapstd::set 的键时,findinsert 操作将花费 O(m log n),其中 m 是需要找到的给定字符串的长度.

【讨论】:

  • 我要赞成这一点,因为指出个别比较不一定是 O(1)。但是后来你对 Java 进行了编辑,我不明白。 hashCode()返回的hash key不是唯一标识,所以在比较两个key的时候还是需要做一个O(m)的字符串比较。
  • 另外,生成哈希码仍然是 O(m),所以不仅速度不快,使用哈希码会更慢(假设它们没有被缓存)
  • @jogojapan 感谢您指出 java.lang.String.hashCode() 事情,通过删除 javaj 部分并坚持提出问题来纠正我的答案。还提出了一个[问题] (stackoverflow.com/questions/17569651/…)
【解决方案3】:

它不会迭代所有元素,它会进行二进制搜索(即 O(log(n)))。它使用 operator

如果你想要一个哈希映射,你可以使用一个 std::unordered_map(在 C++-0x 上添加),它使用一个哈希函数,平均而言(取决于你提供的哈希函数和数据)find() 将是O(1)。

【讨论】:

  • @NicolBolas:我记得在某处读到它不是强制性的平衡树,谢谢您的评论。解决了我的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-31
  • 2022-10-22
  • 1970-01-01
  • 2018-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多