【C++】vector

`vector` 是一种容器,广泛存在于多种编程语言中,如 C++、Rust、Java 等。它是一种动态数组,可以存储任意类型的元素,并且可以根据需要自动调整大小。下面我将详细介绍 `vector` 的概念和使用方法,主要以 C++ 中的 `std::vector` 为例。

1. 概念

  • **动态数组**:与静态数组不同,`vector` 可以在运行时改变其大小。当添加或移除元素时,`vector` 会根据需要自动调整内部存储。

  • **连续内存**:`vector` 内部的元素是存储在一块连续的内存区域中的,这使得随机访问非常高效(O(1) 时间复杂度)。

  • **随机访问**:由于元素存储在连续的内存块中,可以通过索引快速访问任何一个元素。

  • **迭代器支持**:`vector` 支持标准库迭代器,可以方便地遍历元素。

  • **容量与大小**:`vector` 有两个重要的属性,`size()` 表示当前已存储的元素数量,`capacity()` 表示分配的内存空间可以容纳的元素数量。容量通常大于或等于大小,以避免频繁的内存重新分配。

2. 基本操作

  • **创建和初始化**:

  • 默认构造函数:`std::vector<int> vec;`

  • 初始化列表:`std::vector<int> vec = {1, 2, 3, 4};`

  • 指定大小和初始值:`std::vector<int> vec(5, 10); // 创建一个包含5个10的vector`

  • **添加元素**:

  • `push_back(value)`:在 `vector` 的末尾添加一个元素。

  • `emplace_back(args...)`:直接在 `vector` 末尾构造一个新元素,避免了不必要的拷贝或移动。

  • **移除元素**:

  • `pop_back()`:移除 `vector` 末尾的元素。

  • `erase(position)` 或 `erase(start, end)`:移除指定位置或范围内的元素。

  • **访问元素**:

  • `operator\[\]`:通过索引访问元素,例如 `vec0`。

  • `at(index)`:安全地通过索引访问元素,如果索引超出范围则抛出 `out_of_range` 异常。

  • `front()` 和 `back()`:分别获取第一个和最后一个元素。

  • **修改容量**:

  • `reserve(new_capacity)`:预先分配至少 `new_capacity` 大小的内存,不改变 `size()`。

  • `resize(new_size, value)`:调整 `vector` 的大小,用 `value` 填充新增加的元素。

  • **清空**:

  • `clear()`:移除所有元素,但不会释放分配的内存,`capacity()` 不变。

  • **交换**:

  • `swap(other_vector)`:与另一个 `vector` 交换内容。

  • **比较**:

  • `==`, `!=`, `<`, `<=`, `>`, `>=`:用于比较两个 `vector` 的内容。

3. 性能考虑

  • **插入和删除**:在 `vector` 的末端进行插入和删除操作的时间复杂度为 O(1),但在中间或开头进行这些操作的时间复杂度为 O(n),因为需要移动后续的元素。

  • **内存管理**:`vector` 会在需要更多空间时自动增加容量,这可能会导致内存重新分配。为了优化性能,可以在创建 `vector` 时使用 `reserve` 函数来预先分配足够的内存。

4. 容器适配器

`vector` 还可以作为其他容器的基础,比如 `stack`(栈)、`queue`(队列)等,通过限制 `vector` 的某些接口来实现特定的数据结构。

5. 注意事项

  • **线程安全**:C++ 标准库中的 `std::vector` 不是线程安全的,如果多个线程同时访问同一个 `vector`,需要自行实现同步机制。

  • **异常安全性**:大多数 `vector` 的操作提供基本的异常保证,即如果操作抛出异常,`vector` 的状态不会被破坏,但是任何已经完成的操作仍然有效。

以上是对 `vector` 的基本介绍,具体到不同的编程语言,`vector` 的实现细节可能会有所不同。如果你有针对特定语言或者更深入的问题,欢迎继续提问。

相关推荐
小刘在重生~5 小时前
Java常用类|String类详解 + BigDecimal精准计算(含面试题)
java·开发语言·python
随遇而安zx5 小时前
【多线程】---JMM 与 volatile 深度解析
java·多线程
爱吃巧克力的程序媛5 小时前
main.cpp注册 C++ 类到 QML 元对象系统
c++·qt
YYYing.5 小时前
【C++进阶系列 (二)】关于线程堆栈的那些事——函数调用过程
开发语言·c++·函数·线程堆栈
邪修king6 小时前
Re:Linux系统篇(十九):进程篇(八): 进程等待详解:wait/waitpid,僵尸进程到底该如何回收
java·开发语言
啵啵啵鱼6 小时前
DS-顺序表
java·数据结构·笔记·后端·链表·obsidian
我爱写代码i6 小时前
SKAPP SK影视反编译详细教程+源码 含苹果端ipa
开发语言·javascript·ecmascript
TinyMemory6 小时前
Java 面向对象核心入门(七):方法重载 Overload,同一个方法名能干不一样的活
java·面向对象·overload·方法重载
键盘会跳舞6 小时前
【C++多线程】死锁诊断工具实战:从 Windows 到 Linux 的全链路排查
linux·c++·windows·死锁