我找不到答案,但我很确定我不是第一个寻找答案的人。
有没有人知道/使用/看到 STL类容器与双向访问迭代器 O(1)复杂度为插入/擦除/查找?
谢谢。
答案 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?
要点:
有容器提供有限的插入保证
擦除
查找
所以答案是基于容器类型 这就是标准保证人对于如何转化为真正的容器的看法:
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/