C ++ STL列表与设置

时间:2010-02-20 15:40:27

标签: c++ list stl containers

这两个中的哪一个对于随机插入和删除更快?我猜列表,将值作为关键字与集合一样似乎也很有吸引力。 迭代整个容器的性能是否相似?

谢谢!

6 个答案:

答案 0 :(得分:35)

<强>列表

  1. 搜索(线性时间)。
  2. 插入,删除,移动(需要一段时间)。
  3. 可订购元素。
  4. 可以对元素进行排序。
  5. 元素可能重复。
  6. 设置

    1. 搜索(大小对数)。
    2. 插入和删除(一般为logarithimic)。
    3. 元素未按顺序排列。
    4. 元素总是从低到高排序。
    5. 元素是独一无二的。

答案 1 :(得分:19)

对于插入和删除,

std :: list是O(1)。但您可能需要O(n)才能找到插入或删除点。 std :: set是插入和删除的O(log(n)),它通常被实现为红黑树。

考虑找到插入/删除点以便做出选择的努力。

答案 2 :(得分:11)

首先考虑语义,然后考虑性能。

如果你有一组整数,并在其中插入整数6,8,13,8,20,6和50,你最终会得到一个包含以下五个元素的集合:{{1} }

如果您使用列表执行此操作,则最终会得到一个包含以下七个元素的列表:{ 6, 8, 13, 20, 50 }.

那么,你想要什么?将容器的速度与这种不同的语义进行比较是没有意义的。

答案 3 :(得分:3)

在std :: list中,插入和删除本身需要花费一些时间在O(1)中,这意味着非常快,并且最重要的是意味着速度不依赖于数字列表中的元素。

在std :: set中,插入和删除需要花费时间在O(log(N))中,这意味着如果集合中包含许多元素,会慢一些。表达式O中的N(log(N))表示元素的数量。 Grosso modo,它意味着操作所花费的时间与对数成正比(此处基数无关紧要,因为它相当于乘以一个常数,在理论算法分析中被忽略)元素数量在集合中。

但考虑到找到要删除的元素所花费的时间至关重要。如果你必须在容器中搜索要删除的元素,这很可能就是这种情况,那么std :: list将花费很长时间进行搜索,这将是O(N)(这意味着 not快速,因为时间与元素的数量成正比,而不是它的对数),而std :: set将花费一些时间在O(log N)中进行搜索。

另请注意,对于元素很少的容器,这些理论分析绝对无效,在这种情况下,它们隐藏的乘法常数比它所关注的时间函数族更重要。

简而言之:    std :: list =&gt;搜索要删除的元素的速度较慢;更快删除它。    std :: set =&gt;更快地搜索要删除的元素;删除它的速度要慢一些。

但是对于整个操作,对于大量元素,std :: set更好。

您还应该考虑使用哈希表。 Boost,Qt或C ++ 0x中提供了很好的实现。他们及时完成所有这些操作,趋向于O(1)(这意味着非常快)。

答案 4 :(得分:2)

如果您关心速度,那么您应该使用std::vectorstd::list每次插入一个元素时执行一次堆分配,这通常是一个瓶颈。

例外情况是个别物品的复制成本非常高,或者当你拥有大量物品时。在这些情况下,列表可能会表现得更好,因为它不需要在调整大小时移动项目。 std::deque也是一个很好的选择,但您需要对应用程序进行分析,以便在两者之间做出决定。

最后,仅当您需要对项目进行排序(或者如果您不想重复项目)时,才使用std::set。否则它将明显慢于列表或向量。

答案 5 :(得分:2)

您应该在实际数据的实际使用情况下自行衡量效果。检查典型和最差情况下的性能。

尽管std :: vector对于随机插入具有O(N)时间复杂度,std :: set O(log(N))和std :: list O(1),但std :: vector在许多情况下表现最佳。只有当性能不够重要才能花费时间进行测量时,才能采用大O复杂性。

“如果你没有测量你没有工程”(Rico Mariani)