[英]Is erase() in std::vector linear time operation?
页面http://www.cplusplus.com/reference/vector/vector/erase/说
删除元素(破坏)的元素数量加上最后一个元素删除(移动)后的元素数量成线性关系。
因此,如果我要删除某个元素,例如,从长度为n
(n> j)的向量中使用索引j
,它是常量还是线性(O(n))?
或者,如果我在p
Jth
元素之后有p
元素,那么它的阶数为O(p)
-对吗?
从向量中删除N
元素将花费O(N)
的时间复杂度,因为应用程序必须迭代M
元素,并调用每个元素的析构函数,然后将其余元素复制到通过破坏已擦除元素而创建的间隙中。
因此,如果我们有一个包含N
元素的向量,并且从范围(p,q]
删除这些元素,则破坏范围将需要O(qp)
时间复杂度,您可以说是O(1)
,因为p
和q
是常数,那么您将不得不复制/移动范围(q,N]
。由于Nq
是线性的,所以时间复杂度为O(N)
。
我们在一起得到O(N) + O(1) = O(N)
当然,如果删除以数组结尾结尾的范围,则复杂度为O(1)
因为没有要复制/移动的元素。
通过您提供的链接:
与删除(破坏)的元素数量加上最后一个元素删除(移动)后的元素数量成线性关系
这意味着从std::vector
删除N = 1个元素时。 在您的情况下,将对析构函数进行N次调用,该调用等于1。 然后,您将进行等于(nj-1)
M个移动操作。 因此它不是线性的。
因此std :: vector :: erase的复杂度是: O(Deleted_Items_Count) + O(Moved_Items_Count)
。
在您的情况下: 1*Destructor_Time + (nj-1)*Moving_Time
为了在固定时间内从向量中擦除项目,您可以从向量的尾部擦除它们(例如std::vector::pop_back
)
因此,如果您要进行恒定时间的擦除而没有排序的重要性:
auto linear_erase=[](auto& v, const size_t index){
std::swap(v[index], v.back());
v.pop_back();
};
我在SO上了解到该标准是最佳参考。
从23.3.11.1/1 [vector.overview]:
向量是序列容器,最后支持(摊销)恒定时间插入和擦除操作。 在中间插入和擦除需要线性时间。
因此,在这种情况下, erase
既不是恒定时间也不是线性时间。
这主要取决于您执行的操作类型:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.