Page http://www.cplusplus.com/reference/vector/vector/erase/说
线性删除的元素数(破坏)加上数字 删除最后一个元素(移动)后的元素。
所以,如果我从某个长度为01/01/0001
(n> j)的向量中删除一个元素,比如索引为j
- 那么它是常数还是线性的(O(n))?
或者,如果我在n
元素之后有p
个元素,那么它将是Jth
的顺序 - 我是对的吗?
答案 0 :(得分:3)
从向量中删除N
元素将花费O(N)
的时间复杂度,因为应用程序必须遍历M
个元素,并调用每个元素的析构函数,然后复制剩余的破坏被擦除元素所造成的差距元素。
因此,如果我们有一个带有N
元素的向量,并且我们删除范围(p,q]
中的元素,那么破坏该范围将花费O(q-p)
时间复杂度,您可以说是O(1)
,因为p
和q
是常量。那么你将不得不复制/移动范围(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
既不是常数也不是线性时间
它主要取决于您正在执行的操作类型: