感谢您提前查看我的问题。
我正在完成一项大学任务的问题,询问以下内容:
对于每个std :: list< >,std :: map< >,std :: unordered_map< >记录并解释元素插入和查找的保证性能。
在完成大部分工作之前,我没有遇到任何麻烦,直到我来解释列表中的元素查找。
我一直在收集Josuttis和http://www.cplusplus.com的信息,似乎无法找到有关此信息。
我猜是因为这不可能?
答案 0 :(得分:2)
你提到除了list
部分之外你没有遇到任何麻烦,所以我只会回答那个部分。
要回答这个问题,您需要了解std::list
的实施方式。
一些快速搜索提出:
列表容器实现为双向链表。
根据我的解释,保证性能与更糟糕的运行时复杂性意味着相同。
对于双向链接列表中的元素查找,最糟糕的情况是您的列表不包含您尝试查找的项目。在这种情况下,您必须将列表中的每个项目与您要搜索的项目进行比较。因此,此操作的最坏情况运行时复杂性为 O(n),其中n
是列表的大小。
答案 1 :(得分:1)
来自http://www.cplusplus.com/reference/list/list/
list和forward_lists的主要缺点是与其他这些相比 序列容器是他们缺乏对元素的直接访问 他们的立场;例如,要访问列表中的第六个元素 必须从已知位置(如开头或结尾)进行迭代 到那个位置,它在两者之间的距离需要线性时间 这些。它们还消耗一些额外的内存来保持链接 与每个元素相关的信息(这可能是重要的 大型小型元素列表的因素。)
所以,迭代std :: list< > (查找元素)是线性复杂性。此外,您无法通过索引访问元素。
答案 2 :(得分:1)
我建议您阅读以下参考资料: What are the complexity guarantees of the standard containers?
它有许多标准容器的订单复杂性图表,其中一个答案链接到STL复杂性规范。 (http://www.sgi.com/tech/stl/complexity.html)
由于这是一个类项目,我建议您不仅要阅读这些参考文献以获得答案,还要花一些时间在STL标题中,并了解在您的体系结构上实现这些容器。
STL是一种利用真正专家知识的绝妙方式......但如果没有给予尽职调查,它也可能是众所周知的绳索
答案 3 :(得分:1)
如果您想要更正式地声明所支持的内容,这就是标准所说的内容。关于我们可以做的最佳搜索是二进制搜索,例如std::lower_bound
(§25.4.3.1/ 3):
复杂性:最多log 2 (
last − first
)+ O(1)比较。
这只告诉我们比较的数量。要在容器中移动,lower_bound
使用std::advance
。关于我们找到的std :: list(§23.3.5.1/ 1):
list是一个支持双向迭代器[...]
的序列容器
那么,std::advance
如何为提供双向迭代器的集合起作用?
(§24.4.4/ 1):
[...]对于输入,转发和双向迭代器,它们使用++来提供线性时间实现。
因此,为了在列表中找到任何东西(通过值或位置),我们将总体上考虑线性复杂度,并进行对数的比较。说实话,我们可能会更好地使用std::find
(§25.2.5/ 2):
复杂性:对应谓词的大多数
last - first
个应用程序。
两者之间的选择可能并不总是完全明显 - 遍历列表显然是线性的。 std::find
最小化遍历,而std::lower_bound
最小化比较。如果比较比遍历贵很多,std::lower_bound
可能会做得更好。如果比较相当便宜,std::find
可能更好。