简体   繁体   English

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

[英]Is erase() in std::vector linear time operation?

Page http://www.cplusplus.com/reference/vector/vector/erase/ says 页面http://www.cplusplus.com/reference/vector/vector/erase/

Linear on the number of elements erased (destructions) plus the number of elements after the last element deleted (moving). 删除元素(破坏)的元素数量加上最后一个元素删除(移动)后的元素数量成线性关系。

So, if I am deleting an element, say, with index j from vector of some length n (n>j) - will it be constant or linear(O(n))? 因此,如果我要删除某个元素,例如,从长度为n (n> j)的向量中使用索引j ,它是常量还是线性(O(n))?

Or, if I have p elements after Jth element, then it will be of order O(p) - am I right? 或者,如果我在p Jth元素之后有p元素,那么它的阶数为O(p) -对吗?

Deleting N elements from a vector will take a time complexity of O(N) , because the application has to iterate over M elements, and call each element's destructor, then copy the rest of the elements to the gap created by destroying the erased elements. 从向量中删除N元素将花费O(N)的时间复杂度,因为应用程序必须迭代M元素,并调用每个元素的析构函数,然后将其余元素复制到通过破坏已擦除元素而创建的间隙中。

So if we have a vector with N elements, and we erase the elements from the range (p,q] , than destroying the the range will take O(qp) time complexity, which you can say is O(1) , because p and q are constants. then you will have to copy/move the range (q,N] . since Nq is linear, the time complexity is O(N) . 因此,如果我们有一个包含N元素的向量,并且从范围(p,q]删除这些元素,则破坏范围将需要O(qp)时间复杂度,您可以说是O(1) ,因为pq是常数,那么您将不得不复制/移动范围(q,N] 。由于Nq是线性的,所以时间复杂度为O(N)

together we get O(N) + O(1) = O(N) 我们在一起得到O(N) + O(1) = O(N)

of course, if you delete a range that ends in the end of the array, the Complexity is O(1) because there are no elements to copy/move. 当然,如果删除以数组结尾结尾的范围,则复杂度为O(1)因为没有要复制/移动的元素。

From the link you provided: 通过您提供的链接:

Linear on the number of elements erased (destructions) plus the number of elements after the last element deleted (moving) 与删除(破坏)的元素数量加上最后一个元素删除(移动)后的元素数量成线性关系

This means that when deleting N=1 elements from the std::vector . 这意味着从std::vector删除N = 1个元素时。 It will take make N call to the destructor which is equal to 1 in your case. 在您的情况下,将对析构函数进行N次调用,该调用等于1。 Then it will make M move operation which is equal to (nj-1) in your case. 然后,您将进行等于(nj-1) M个移动操作。 So it is linear not a constant. 因此它不是线性的。

So the complixity of std::vector::erase is: O(Deleted_Items_Count) + O(Moved_Items_Count) . 因此std :: vector :: erase的复杂度是: O(Deleted_Items_Count) + O(Moved_Items_Count)

In your case: 1*Destructor_Time + (nj-1)*Moving_Time 在您的情况下: 1*Destructor_Time + (nj-1)*Moving_Time


In order to erase items from vector in constant time,you may erase them from the tail of the vector(eg std::vector::pop_back ) 为了在固定时间内从向量中擦除项目,您可以从向量的尾部擦除它们(例如std::vector::pop_back

So if you want a constant time erasing with no importance of sorting: 因此,如果您要进行恒定时间的擦除而没有排序的重要性:

auto linear_erase=[](auto& v, const size_t index){
    std::swap(v[index], v.back());
    v.pop_back();
};

I learned here on SO that the standard is the best reference. 我在SO上了解到该标准是最佳参考。

From 23.3.11.1/1 [vector.overview]: 23.3.11.1/1 [vector.overview]:

A vector is a sequence container that supports (amortized) constant time insert and erase operations at the end; 向量是序列容器,最后支持(摊销)恒定时间插入和擦除操作。 insert and erase in the middle take linear time. 在中间插入和擦除需要线性时间。

So, in this case erase is neither constant nor linear time. 因此,在这种情况下, erase既不是恒定时间也不是线性时间。
It mostly depends on the kind of operation you are performing: 这主要取决于您执行的操作类型:

  • It's constant if you are erasing at the end of the vector, 如果要在向量的末尾擦除,这是恒定的,
  • Otherwise it's linear. 否则它是线性的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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