我需要使用以下支持的操作来维护项目(某个对象(的列表:
- 末端插入
- 从任何位置中删除
STL列表似乎是正确的选择。但是,如何在恒定时间内进行第二次操作?我可以将指向每个节点的指针保存在某处并直接删除它们,但擦除需要一个迭代器,因此这不起作用。
用法示例:
items = list<myobj>..
items.push_back(obj1)
items.push_back(obj2)
items.push_back(obj3)
items.remove(obj2) // <- How to do this in constant time.
如果push_back以某种方式提供了对节点的访问权限,我可以使用:
map[obj1] = items.push_back(obj1)
items.remove(map[obj1])
一种选择是在地图中使用迭代器,有没有更简单的方法?
折衷方案是像大多数 std::set 实现一样是一棵红黑树。它是O(log n(用于插入,搜索和删除。树基本上是最终的折衷数据结构。他们没有什么了不起的,但他们总是把工作做得足够好。
否则,使用链表和向量来分析你的代码,并找出调整向量的大小是否真的像它可能的那样糟糕(这取决于你这样做的频率(。
可能有一个更好(不优雅,但非常有效(的解决方案可以解决您的问题。您还没有提到您将如何使用列表,但是如果您可以将值留出未使用状态,则可以使用向量并简单地将元素标记为已删除,而不是实际删除它。或者使用向量和具有单独的位集(或 C++03 vector<bool>
(告诉您项目是否已删除或有效。要删除它,您只需翻转位图中的位。迭代时,请记住在处理内容之前检查删除位图。如果内存不是问题,只有速度和易用性/清晰度很重要,请将vector<object>
替换为vector<pair<bool, object>>
,其中bool
是删除标志。
你可能想看看Boost.MultiIndex。这允许您在数据结构上组合多个索引。因此,您可以持续查找和删除任何元素,但代价是线性空间开销。