当您需要订购时,请使用订购的容器。以后再支付分拣费用是没有意义的。
您当前的解决方案是:
- 插入
O(1)
- 恢复
O(N log N)
- 删除
O(N)
(在不保留另一个索引的情况下尽可能好)
只需使用 astd::multi_map
你就可以拥有:
- 插入
O(log N)
- 检索
O(log N)
<- 好多了不是吗?我们需要找到范围的终点
- 移动
O(N)
现在,您可以使用 a 做得更好std::map< key, std::vector<value> >
:
- 插入
O(log M)
whereM
是不同键的数量
- 检索
O(1)
(begin
保证摊销常数时间)
- 移动
O(N)
你不能真正推动随机删除......除非你愿意在那里保留另一个索引。例如:
typedef std::vector<value_type> data_value_t;
typedef std::map<key_type, data_value_t> data_t;
typedef std::pair<data_t::iterator,size_t> index_value_t;
// where iterator gives you the right vector and size_t is an index in it
typedef std::unordered_map<value_type, index_value_t> index_t;
但是保持第二个索引是最新的很容易出错......并且将以牺牲其他操作为代价!例如,使用这种结构,您将拥有:
- 插入
O(log M)
--> 哈希映射中插入的复杂度是O(1)
- 检索
O(N/M)
--> 需要对向量中的所有值进行去索引N/M
,平均有
- 移除
O(N/M)
--> 在 hash map 中查找O(1)
,取消引用O(1)
,从向量中移除,O(N/M)
因为我们需要移动大约一半的向量内容。使用 alist
会产生O(1)
......但可能不会更快(取决于内存权衡的元素数量)。
还要记住,哈希映射复杂性是摊销的。触发重新分配,因为您超出了负载因子,并且此特定插入将花费很长时间。
我真的会std::map<key_type, std::vector<value_type> >
代替你去。这是最划算的。