繁体   English   中英

在std :: vector线性时间操作中是否为delete()?

[英]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) ,因为pq是常数,那么您将不得不复制/移动范围(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM