STL喜欢具有O(1)性能的容器

时间:2009-10-21 14:08:31

标签: c++ stl

我找不到答案,但我很确定我不是第一个寻找答案的人。 有没有人知道/使用/看到 STL类容器双向访问迭代器 O(1)复杂度为插入/擦除/查找
谢谢。

7 个答案:

答案 0 :(得分:10)

没有抽象数据类型,插入,擦除和查找的O(1)复杂度也提供了双向访问迭代器。

编辑:

对于任意大的域都是如此。给定一个足够小的域,您可以使用数组和双向链表实现插入,擦除和查找的O(1)复杂度集和双向访问迭代器:

std::list::iterator array[MAX_VALUE];
std::list list;

初​​始化:

for (int i=0;i<MAX_VALUE;i++)
    array[i] = list.end();

插入:

if (array[value] != list.end())
    array[value] = list.insert(value);

擦除:

if (array[value] != list.end()) {
    array[value].erase();
    array[value] = list.end();
}

查找

array[value] != list.end()

答案 1 :(得分:4)

tr1的unordered_set(也可用于提升)可能就是你要找的东西。您没有指定是否需要序列容器,并且未指定用于提供O(1)查找的(即。向量对索引进行O(1)查找,上面提到的unordered_set有基于元素本身的O(1)平均大小写查找。)

答案 2 :(得分:1)

关联数组(散列表)具有O(1)查找复杂性,而双向链接列表具有O(1) bidi迭代。

答案 3 :(得分:1)

我在搞乱存储优化时所做的一个技巧是实现一个添加了O(1)[1]的链表,然后进行缓存操作,提供一个更快的O(n)查找结构[ 2]。实际的缓存需要一些O(n)时间来构建,我没有专注于擦除。所以我“欺骗了一下”并将工作推向了另一个操作。但是如果你不需要进行大量的添加/删除,那么这不是一个糟糕的方法。

[1]存储结束指针并仅添加到结尾。不需要遍历。
[2]我创建了一个动态数组[3]并搜索它。由于数据没有排序,我无法在O(lg n)时间内对其进行binsearch。虽然我想我可以对它进行分类 [3]数组具有比列表更好的缓存性能。

答案 4 :(得分:1)

STL的所有复杂性保证的完整列表可以在这里找到:
What are the complexity guarantees of the standard containers?

要点:


  • 插入:没有容器保证O(1)用于通用插入。
    • 唯一拥有genric insert gurtatee的容器是:'Associative Container'。这是O(ln(n))
  • 有容器提供有限的插入保证

    • 提前扣押保证在O(1)
    • 的头部插入一个插入物
    • 后序列保证在O(1)的尾部插入
  • 擦除

    • 关联容器保证O(1)擦除(如果你有一个迭代器)。
  • 查找

    • 如果您的意思是通过查找访问元素(因为没有容器具有O(1)查找功能)。
    • 然后随机访问容器是唯一具有O(1)访问权限的容器

所以答案是基于容器类型 这就是标准保证人对于如何转化为真正的容器的看法:

std::vector:    Sequence,   Back        Sequence,                   Forward/Reverse/Random Container
std::deque:     Sequence,   Front/Back  Sequence,                   Forward/Reverse/Random Container
std::list:      Sequence,   Front/Back  Seuqence,                   Forward/Reverse Container
std::set:       Sorted/Simple/Unique    Associative Container,      Forward Container
std::map:       Sorted/Pair/Unique      Associative Container,      Forward Container
std::multiset:  Sorted/Simple/Multiple  Associative Container,      Forward Container
std::multimap:  Sorted/Pair/Multiple    Associative Container,      Forward Container

答案 5 :(得分:1)

实际上,使用数组(向量)并延迟插入和删除的成本可能就足够了。

通过将元素标记为已删除来删除元素,将元素插入到所需位置的bin中,并记住较大索引的偏移量。

插入和删除将在方便的时候进行O(1)加O(N)清理;查找将是O(1)平均值,O(自上次清理以来的更改次数)最差情况。

答案 6 :(得分:0)

你将无法将所有要求都放入一个容器......需要付出的代价;) 不过,也许这对你很有意思: http://www.cplusplus.com/reference/stl/