在std :: vector线性时间操作中擦除()吗?

时间:2016-06-02 09:05:44

标签: c++ vector erase

Page http://www.cplusplus.com/reference/vector/vector/erase/

  

线性删除的元素数(破坏)加上数字   删除最后一个元素(移动)后的元素。

所以,如果我从某个长度为01/01/0001(n> j)的向量中删除一个元素,比如索引为j - 那么它是常数还是线性的(O(n))?

或者,如果我在n元素之后有p个元素,那么它将是Jth的顺序 - 我是对的吗?

3 个答案:

答案 0 :(得分:3)

从向量中删除N元素将花费O(N)的时间复杂度,因为应用程序必须遍历M个元素,并调用每个元素的析构函数,然后复制剩余的破坏被擦除元素所造成的差距元素。

因此,如果我们有一个带有N元素的向量,并且我们删除范围(p,q]中的元素,那么破坏该范围将花费O(q-p)时间复杂度,您可以说是O(1),因为pq是常量。那么你将不得不复制/移动范围(q,N]。由于N-q是线性的,因此时间复杂度为O(N)

我们一起获得O(N) + O(1) = O(N)

当然,如果删除以数组末尾结尾的范围,则复杂性为O(1),因为没有要复制/移动的元素。

答案 1 :(得分:2)

从您提供的链接:

  

线性删除的元素数(破坏)加上数字   删除最后一个元素后的元素(移动)

这意味着从std::vector删除N = 1个元素时。在你的情况下,需要使N调用析构函数,它等于1。然后它将使M移动操作在您的情况下等于(n-j-1)。所以它是线性的而不是常数。

所以std :: vector :: erase的复杂性是:O(Deleted_Items_Count) + O(Moved_Items_Count)

在您的情况下:1*Destructor_Time + (n-j-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();
};

答案 2 :(得分:0)

我在这里了解到标准是最好的参考。

来自23.3.11.1/1 [vector.overview]:

  

向量是一个序列容器,它支持(分期)常量时间插入和擦除操作;在中间插入和擦除需要线性时间。

因此,在这种情况下,erase既不是常数也不是线性时间 它主要取决于您正在执行的操作类型:

  • 如果你在向量的末尾擦除它是不变的,
  • 否则它是线性的。