在列表中搜索c ++?

时间:2013-01-16 23:04:13

标签: c++ search element stdlist

感谢您提前查看我的问题。

我正在完成一项大学任务的问题,询问以下内容:

  

对于每个std :: list< >,std :: map< >,std :: unordered_map< >记录并解释元素插入和查找的保证性能。

在完成大部分工作之前,我没有遇到任何麻烦,直到我来解释列表中的元素查找。

我一直在收集Josuttis和http://www.cplusplus.com的信息,似乎无法找到有关此信息。

我猜是因为这不可能?

4 个答案:

答案 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可能更好。