C++ Vector
C++ Vector
vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。
vector的用法类似于Python中的list
数据类型。
基本概念
std::vector
是动态数组,支持随机访问- 内存连续存储,支持下标操作
- 插入/删除尾部效率高,在中间或头部插入效率低
- 会自动扩容,容量(
capacity
) ≥ 元素个数(size
)
容器特性
顺序特性
顺序容器中的元素按照严格的线性顺序排序,可以通过元素在序列中的位置访问对应的元素
动态数组
支持对序列中的任意元素进行快速直接访问,甚至可以通过指针算术进行该操作。
能够感知内存分配器
容器使用一个内存分配器对象来动态地处理它的存储需求
基本函数实现
构造函数
vector()
: 创建一个空的vectorvector(int nSize)
: 创建一个vector,元素个数为nSizevector(int nSize, const t& t)
: 创建一个vector,元素个数为nSize,且值均为tvector(const vector&)
: 复制构造函数vector(begin, end)
: 复制[begin, end)
区间内的另一个数组的元素到vector中
1 2 3 4 5 6 7 8 9 10 11 12
std::vector<int> vec; vec.push_back(1); std::vector<int> vec(2); std::vector<int> vec(1,1); std::vector<int> vec = {1, 2, 3, 4}; std::vector<int> vec{1, 2, 3, 4, 5}; std::vector<int> vec_copy(vec); std::vector<int> vec2(vec.begin(), vec.begin()+3);
增加函数
void push_back(const T& x)
: 向量尾部添加一个元素xiterator insert(iterator it, const T& x)
: 向量中迭代器指向的位置前前增加一个元素xiterator insert(iterator it, int n, const T& x)
: 向量中迭代器指向的位置前增加n个相同的元素xiterator insert(iterator it, const_iterator first, const_iterator last)
: 向量中迭代器指向元素前插入另一个相同类型向量的[first,last)
间的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vector<int> vec = {1, 2, 3, 4}; vec.push_back(7); auto it = vec.begin() + 1; vec.insert(it, 7); // 1, 7, 2, 3, 4 auto it = vec.begin() + 1; vec.insert(it, 2, 7); // 1, 7, 7, 2, 3, 4 // vec.insert(vec.begin() + 1, 2, 7); vector<int> vec1 = {1, 4}; vector<int> vec2 = {2, 3}; vec1.insert(vec1.begin() + 1, vec2.begin(), vec2.end()); // 结果: [1, 2, 3, 4]
删除函数
iterator erase(iterator it)
: 删除向量中迭代器指向元素iterator erase(iterator first, iterator last)
: 删除向量中[first,last)
中元素void pop_back()
: 删除向量中最后一个元素void clear()
: 清空向量中所有元素
1 2 3 4 5 6 7 8
vector<int> vec = {1, 2, 3, 4}; auto it = vec.begin() + 1; vec.erase(it); vec.erase(vec.begin() + 1); vec.erase(vec.begin() + 1, vec.end() - 1);
遍历函数
reference at(int pos)
: 返回pos
位置元素的引用reference front()
: 返回首元素的引用reference back()
: 返回尾元素的引用iterator begin()
: 返回向量头指针,指向第一个元素iterator end()
: 返回向量尾指针,指向向量最后一个元素的下一个位置reverse_iterator rbegin()
: 反向迭代器,指向最后一个元素reverse_iterator rend()
: 反向迭代器,指向第一个元素之前的位置
判断函数
bool empty() const
: 判断向量是否为空,若为空,则向量中无元素
大小函数
int size() const
: 返回向量中元素的个数int capacity() const
: 返回当前向量所能容纳的最大元素值int max_size() const
: 返回最大可允许的 vector 元素数量值
其他函数
void swap(vector&)
: 交换两个同类型向量的数据void assign(int n, const T& x)
: 设置向量中前n个元素的值为xvoid assign(const_iterator first, const_iterator last)
: 向量中[first,last)
中元素设置成当前向量元素
常用成员方法
方法 | 作用 |
---|---|
push_back(x) | 在尾部插入元素 |
pop_back() | 删除尾部元素 |
insert(pos, x) | 在指定位置插入元素 |
erase(pos) | 删除指定位置元素 |
erase(first, last) | 删除范围内元素 |
clear() | 删除所有元素 |
operator[] | 通过下标访问元素(不检查越界) |
at(i) | 通过下标访问元素(检查越界,抛异常) |
front() | 返回第一个元素 |
back() | 返回最后一个元素 |
begin() | 返回指向第一个元素的迭代器 |
end() | 返回指向最后一个元素后面的位置迭代器 |
rbegin() / rend() | 反向迭代器 |
size() | 当前元素个数 |
capacity() | 当前分配的空间大小 |
resize(n) | 改变大小,多余元素会被删除或新元素初始化 |
reserve(n) | 预留容量,避免频繁扩容 |
shrink_to_fit() | 把容量缩小到正好容纳当前元素数 |
empty() | 判断是否为空 |
swap(v2) | 与另一个 vector 交换内容 |
常见操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v; // 定义一个空 vector<int>
// 插入
v.push_back(10);
v.push_back(20);
v.push_back(30);
// 遍历
cout << "Elements: ";
for (int x : v) cout << x << " ";
cout << endl;
// 下标访问
cout << "v[1] = " << v[1] << endl;
// 大小
cout << "size=" << v.size() << " capacity=" << v.capacity() << endl;
// 删除最后一个
v.pop_back();
// 插入指定位置
v.insert(v.begin() + 1, 15);
// 删除指定位置
v.erase(v.begin());
// 清空
v.clear();
cout << "Final size=" << v.size() << endl;
}
vector对象的定义和初始化
1
2
#include <vector>
using namespace std;
std::vector
是一个类模板(class template),在编译时根据指定的元素类型T
生成对应的类
1
2
3
4
template <
class T, // 存储的元素类型
class Allocator = std::allocator<T> // 内存分配器(默认用std::allocator>
> class vector;
例如:
1
2
vector<int> v1; // 实例化为存int的动态数组
vector<string> v2; // 实例化为存string的动态数组
和数组对比
vector
动态分配,支持自动扩容,安全且方便。- 普通数组大小固定,越界访问不会报错。
- 推荐优先用
vector
代替裸数组。
动态分配和指针
1
2
3
4
std::vector<int> vec = {1, 2, 3, 4};
int* p = &vec[2];
vec.push_back(5);
std::cout << *p << std::endl;
在上面的程序中,首先定义了一个容量为4的vector,并且定义了一个指向向量第二个数值的指针
指针 p
指向 vec[2]
(即值为 3
的元素),保存了该元素的内存地址。
接着使用push_back
函数增加了一个元素,此时由于vec
默认的容量为4,添加后为5个元素,超出了容量,触发自动扩容机制
这时候会重新为vec
申请容量更大(大于5)的内存,并且将元素复制到新的内存中,释放旧内存
重新分配后,原来所有指向vec
的迭代器、引用和指针都有可能失效,p
成为悬空指针
永远不要在可能重新分配的操作(
push_back
、resize
、insert
等)中保留指向std::vector
元素的原始指针。重新分配后使用索引或更新指针。
本文由作者按照 CC BY 4.0 进行授权