【发布时间】:2023-04-15 22:11:01
【问题描述】:
std::map 的时间复杂度是多少? 在最坏的情况下它会退化吗? 还是由实现决定,我们不知道?
【问题讨论】:
-
什么的时间复杂度?无论如何,看看here。
-
@juanchopanza 会不会是数据检索以外的东西?
-
@ValekHalfHeart 是的。例如数据插入。或删除元素。
std::map 的时间复杂度是多少? 在最坏的情况下它会退化吗? 还是由实现决定,我们不知道?
【问题讨论】:
查找与 log(N) 成正比。在典型情况下(实现为红黑树)比较次数最多可达 Log2N 的两倍。
插入次数通常也与 Log2N 成正比——但是当您插入许多已按顺序排列的项目时,有一项特殊规定1。在这种情况下,您可以为将要插入的位置指定“提示”。当该提示正确时,每次插入都是(摊销)O(1) 而不是 O(Log N),因此按排序顺序插入一系列项目是线性的,而不是 N log(N)。您指定的提示是一个迭代器,指向要插入的项目之后的位置。
例如,如果您在一个文件中有许多按排序顺序排列的项目,并且您想将它们插入到地图中,您可以指定 your_map.end() 作为“提示”,构建地图将需要 O( N) 复杂度而不是 O(N Log N) 复杂度。
1. 从技术上讲,这适用于您插入项目的任何时候,而不仅仅是当您按顺序插入它们时——但到目前为止,您有一个合理的“提示”可用的最常见情况是当您按顺序插入项目时。
【讨论】:
这取决于实现,您无法仅通过查看语言规范将任何类型的复杂性与 std::map 相关联。
通常std::map 实现为Red-Black Tree,您可以找到有关此类容器here 的Big-O 属性的所有信息。
值得注意的是,与msvc 或gcc 等流行编译器一起提供的标准库相比,使用B-trees 实现这种容器的标准库不太流行,这会导致内存使用率降低,因为B-tree 通常比 RB-tree 占用更少的内存。
例如click here。
【讨论】:
std::map 操作相关联,因为它们已写入规范。特别是,std::map 的“排序数组”实现不符合这个原因(以及指针/迭代器无效要求)。
通常为操作指定时间复杂度。在您的情况下,lookup 和 insert 似乎相关。
请参阅http://www.sgi.com/tech/stl/complexity.html,了解 STL 容器的保证复杂性。还有这个 http://www.sgi.com/tech/stl/AssociativeContainer.html 在关联容器上。
在这里找到另一个来源:
std::map 的查找是 log(map 中的元素数)。
【讨论】:
如果您要询问 std::map 的查找时间复杂性,那将是 O(log(n)),因为 stl 将 std::map 库实现为树(二叉树)数据结构。
更多信息在这里: http://www.cplusplus.com/reference/map/map/
这里也是常用的std::unordered_map,它是你的hashmap(因此没有排序),查找速度为O(1),但是,根据数据结构的设计,它使用的内存比Tree多。
【讨论】: