为什么std::vector::insert复杂度是线性的(而不是常量)
Why is std::vector::insert complexity linear (instead of being constant)?
假设我在大小为'n'的std::vector<mytype>
的第I个位置插入p个新元素。
由于std::vector
中的项保证为其元素使用连续的存储位置,因此看起来这将花费我4个步骤来完成上述操作:
1)如果我们没有空间,可能会重新分配向量,基本上是将其大小加倍。但这是一个常数时间操作(尽管是一个非常大的操作)。
2)接下来是一个从索引0到索引i-1的从旧向量到新向量的元内存。
3)然后复制'p'新条目插入到索引。
4)然后为从旧向量到新向量从i+1到n个索引的所有项创建另一个memcpy。
不都是常数时间操作吗?那么插入本身不应该是一个常数时间操作吗?那么为什么std::vector::insert
对插入的元素数量(复制/移动构造)加上位置(移动)后的元素数量是线性的?
不都是常数时间操作吗?
不,memcpy
和memmove
的时间复杂度在被复制或移动的块的大小上是线性的,因为每个被移动的k
字节都需要被精确地触摸一次。被移动的块的大小是sizeof(T) * N
,使得时间也是线性的。
即使在vector的末尾添加一个元素也具有线性复杂性,因为在重新分配时复制数据(然而,在vector的末尾添加N
元素具有平摊线性复杂性,即每项平摊常数复杂度)。
您提到可能会有重新分配,那么在这种情况下,时间复杂度显然将是线性,正如上面的答案所述。但是,即使没有重新分配,时间复杂度也将线性,因为vector::insert()函数的复杂度为O(n+m),其中n为插入的元素数, m为移动的元素数。
示例:假设我们在vector前面插入一个元素,那么vector中存在的所有元素都将向右移动(这需要线性时间),以便将元素插入到前面。时间复杂度为0 (1 + elements_in_vector)
- #定义c-预处理器常量..我做错了什么
- 用C++中的一个变量定义一个常量
- 什么时候在C++中返回常量引用是个好主意
- 代理对象的常量正确性
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 通过多个头文件使用常量变量
- 在cuda线程之间共享大量常量数据
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 是默认情况下分配给char数组常量的值
- 私有类型的静态常量成员
- 类似枚举的计算常量
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 为什么我可以通过引用修改常量返回
- 如何创建长度由常量参数指定的数组
- 当一个值是非常量但用常量表达式初始化时使用constexpr
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- 隐式常量/非常量运算符布尔
- 使用递归在常量空间和线性时间中向后打印链表
- 为什么std::vector::insert复杂度是线性的(而不是常量)