std::vector 实现是否使用内部数组或链表或其他
Does the std::vector implementation use an internal array or linked list or other?
有人告诉我 std::vector 在内部实现上有一个 C 风格的数组,但这不会否定拥有动态容器的全部目的吗?
那么在向量中插入值是 O(n) 操作吗?还是像链表中那样的 O(1)?
从 C++11 标准中,在"序列容器"库部分(强调我的):
[23.3.6.1 类模板
vector
概述][矢量概述]
向量是一个序列容器,它支持(摊销)恒定时间插入和擦除操作,在 结束;中间的插入和擦除需要线性时间。不过,存储管理是自动处理的 可以给出提高效率的提示。
这并没有破坏动态大小的目的 - 矢量的部分要点是,不仅访问单个元素非常快,而且扫描矢量具有非常好的内存局部性,因为所有内容都紧密地包装在一起。实际上,拥有良好的内存局部性非常重要,因为它大大减少了缓存未命中,这对运行时有很大的影响。在许多情况下,这是vector
优于list
的主要优势,尤其是在需要迭代整个容器的频率高于需要添加或删除元素的情况下。
std::vector
中的内存必须是连续的,因此它通常表示为数组。
你关于std::vector
操作的复杂性的问题是一个很好的问题 - 我记得当我第一次开始编程时,我自己也想知道这一点。如果将元素附加到 std::vector
,则它可能必须执行调整大小操作并将所有现有元素复制到新数组中。在最坏的情况下,这将需要时间 O(n)。但是,附加元素的摊销成本为 O(1)。我们的意思是,附加到std::vector
的任何 n 序列的总成本始终为 O(n)。这背后的直觉是,std::vector
通常会过度分配其数组中的空间,留下大量可用插槽供元素插入而无需重新分配。因此,大多数附加将花费时间 O(1),即使时不时地会有一个需要时间 O(n)
也就是说,在std::vector
的其他地方执行插入的成本将是O(n),因为您可能需要将所有内容都移低。
您还问为什么会这样,如果它违背了拥有动态数组的目的。即使std::vector
只是像托管阵列一样运行,它仍然是对原始阵列的胜利。std::vector
知道它的大小,可以做边界检查(用at
),是一个实际的对象(不像数组),并且不会衰减到指针。这些额外的功能 - 加上使追加快速工作的额外逻辑 - 几乎总是值得的。
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 有没有办法使用 strcpy 将字符串数组复制到另一个字符串或其他数组中?
- 还有其他方法可以在数组中写入多维数组吗?
- 为什么在某些编译器中可以声明像int myarr[noconstant]这样的数组;而不是在其他编译器中?
- 严格的别名是否会阻止您通过其他类型写入 char 数组?
- Sizeof返回的是指针大小,而不是数组大小.有其他方法可以找到尺寸吗
- 将十六进制字符数组存储在字节数组中,而无需更改为 ASCII 或其他任何东西
- 如何将char数组声明为函数参数?或告诉我此代码中还有其他问题?
- 在 C++ 中使用递归填充 D2 数组,有时工作正常,其他时会引发异常
- 使用类的其他成员变量定义类的成员变量数组
- 对数组进行排序并匹配其他数组
- 对相同其他数组旁边的数组进行排序
- 对数组进行排序并匹配其他数组并得到错误
- 将 2D 数组设置为函数,并根据需要在其他地方调用它
- C++ 在构造函数中传递数组而不在其他地方定义它们
- 我如何在课堂中使用其他类别的数组
- 使用传入数组初始化其他数组
- 我无法将二维数组的两个元素的差异分配给C++中其他数组的元素?
- 未签名的char数组到stl ::映射或其他容器中的键
- 是否可以在函数调用中构造和传递数组/其他容器