C++容器 vector
vector 是表示可以改变大小的数组的序列容器。
就像 array 一样,vector 对它们的元素使用连续的存储位置,这意味着它们的元素也可以使用指向其元素的常规指针上的偏移量来访问,并且效率与 array 相同。但是与 array 不同的是,它们的大小可以动态改变,其存储由容器自动处理。
vector 在内部使用动态分配的数组存储其元素。插入新元素时,可能需要重新分配该数组以增大其大小,这意味着分配新数组并将所有元素移至该数组。就处理时间而言,这是一项相对昂贵的任务。
所以,vector 可能会分配一些额外的存储空间以适应可能的增长,因此,该容器的实际容量可能会大于包含其元素的个数(即其大小)所严格要求的存储容量。vector 可以实现不同的增长策略,以便在内存使用和重新分配之间取得平衡,但是在任何情况下,重新分配仅应以大小的对数增长间隔进行,以便可以在 vector 末尾插入单个元素提供线性(O(n))的时间复杂性。
因此,与 array 相比,vector 消耗更多内存以换取管理存储和有效的动态增长能力。
与其它动态序列容器(deque,list 和 forward_list)相比,vector 非常有效地访问其元素(就像 array 一样),并且相对高效地从其末尾添加或删除元素。对于涉及在末尾以外的位置插入或删除元素的操作,它们的性能比其它动态序列容器差,并且与 list 和 forward_list 相比,迭代器和引用的一致性更差。
模板参数(Template parameters)
template <class _Ty, class _Alloc = allocator<_Ty>>//_Ty是元素的类型,_Alloc是分配器类型,有默认的分配器
成员函数(Member functions)
using value_type = _Ty;
using allocator_type = _Alloc;
using pointer = typename _Alty_traits::pointer;
using const_pointer = typename _Alty_traits::const_pointer;
using reference = _Ty&;
using const_reference = const _Ty&;
using size_type = typename _Alty_traits::size_type;
using difference_type = typename _Alty_traits::difference_type;
using iterator = _Vector_iterator<_Scary_val>;
using const_iterator = _Vector_const_iterator<_Scary_val>;
using reverse_iterator = _STD reverse_iterator<iterator>;
using const_reverse_iterator = _STD reverse_iterator<const_iterator>;
成员函数(Member functions)
函数名 | 函数功能 |
---|---|
begin | 返回第一个元素的 iterator |
end | 返回最后一个元素的下一个元素的 iterator |
rbegin | 返回反向迭代器反向开始的 iterator |
rend | 返回反向迭代器返回到反向端点的 iterator |
cbegin | 返回第一个元素的 const_iterator |
cend | 返回最后一个元素的下一个元素的 const_iterator |
crbegin | 返回反向迭代器反向开始的 const_iterator |
crend | 返回反向迭代器返回到反向端点的 const_iterator |
size | 返回大小 |
max_size | 返回最大大小 |
resize | 重新申请并改变当前 vector 对象的有效空间(size)大小 |
capacity | 返回分配的存储容量的大小 |
empty | 测试数组是否为空 |
reserve | 重新申请并改变当前 vector 对象的总空间(capacity)大小 |
shrink_to_fit | 降低其容量和 size 匹配 |
operator[] | 访问元素 |
at | 访问元素 |
front | 访问第一个元素 |
back | 访问最后一个元素 |
data | 获取指向数据的指针 |
assign | 拷贝 |
push_back | 在末尾添加元素 |
pop_back | 删除最后一个元素 |
insert | 插入元素 |
erase | 删除元素 |
swap | 交换内容 |
clear | 清除内容 |
emplace | 构造和插入元素 |
emplace_back | 在最后构造并插入元素 |
get_allocator | 获取分配器 |
示例:
#include <vector>
#include <iostream>
using namespace std;
const int SIZE = 10;
int main() {
//默认初始化,vector为空, size为0,表明容器中没有元素,而且 capacity 也返回 0,意味着还没有分配内存空间。
//这种初始化方式适用于元素个数未知,需要在程序中动态添加的情况。
vector<int> a;
//两种方式等价,b 初始化为 a 的拷贝,b 必须与 a 类型相同。
//也就是同为int的vector类型,a 将具有和 b 相同的容量和元素。
vector<int> b(a);// vector<int> b = a;
//c 初始化为列表中元素的拷贝,列表中元素必须与 c 的元素类型相容。
//必须是与整数类型相容的类型,整形会直接拷贝,其他相容的类型会进行类型转换。
vector<int> c{ 0,1,2,3,4,5,6,7,8,9 };//vector<int> c = { 0,1,2,3,4,5,6,7,8,9 };
//d 初始化为两个迭代器指定范围中元素的拷贝(前闭后开),范围中的元素类型必须与 d 的元素类型相容
vector<int> d(c.begin(), c.end());
//默认值初始化,e 中将包含 10 个元素,每个元素进行缺省的值初始化,对于int,也就是被赋值为0。
//e 被初始化为包含 10 个 0。当程序运行初期元素大致数量可预知,而元素的值需要动态获取的时候,可采用这种初始化方式。
vector<int> e(10);
//指定值初始化,f 被初始化为包含 10 个值为 1 的int
vector<int> f(10, 1);
//赋值
vector<int> v(SIZE);
for (int i = 0; i < v.size(); i++) {
v[i] = rand();
}
//输出
for (int i = 0; i < v.size(); i++) {
cout << "v 的第 " << i << " 个元素:" << v[i] << " " << endl;
}
cout << endl;
//8种迭代器
auto begin = v.begin(); //返回第一个元素的iterator
auto end = v.end(); //返回最后一个元素的下一个元素的iterator
auto rbegin = v.rbegin(); //返回最后一个元素的iterator
auto rend = v.rend(); //返回第一个元素的前一个元素的iterator
auto cbegin = v.cbegin(); //返回const_iterator,该const_iterator指向第一个元素
auto cend = v.cend(); //返回const_iterator,该iconst_iterator指向最后一个元素的下一个元素
auto crbegin = v.crbegin(); //返回const_iterator,该const_iterator指向最后一个元素
auto crend = v.crend(); //返回const_iterator,该const_iterator指向第一个元素的前一个元素
//函数
cout << "vector.size() = " << v.size() << endl;
cout << "vector.max_size() = " << v.max_size() << endl;
cout << "vector.capacity() = " << v.capacity() << endl;
cout << "vector.empty() = " << v.empty() << endl;
cout << "vector.at(0) = " << v.at(0) << endl;
cout << "vector.front() = " << v.front() << endl;
cout << "vector.back() = " << v.back() << endl;
cout << "vector.data() = " << v.data() << endl;
cout << endl << "change size and capacity" << endl;
v.resize(5);
v.reserve(100);
cout << "vector.size() = " << v.size() << endl;
cout << "vector.capacity() = " << v.capacity() << endl;
cout << endl << "降低其容量和 size 匹配" << endl;
v.shrink_to_fit();
cout << "vector.size() = " << v.size() << endl;
cout << "vector.capacity() = " << v.capacity() << endl;
vector<int> t;
cout << endl << "assign的第一种用法" << endl;
t.assign(v.begin(), v.end());
for (int i = 0; i < t.size(); i++) {
cout << "t 的第 " << i << " 个元素:" << t[i] << " " << endl;
}
cout << endl << "assign的第二种用法" << endl;
t.clear();
t.assign(SIZE, 1);
for (int i = 0; i < t.size(); i++) {
cout << "t 的第 " << i << " 个元素:" << t[i] << " " << endl;
}
cout << endl << "push_back(100)" << endl;
t.push_back(100);
for (int i = 0; i < t.size(); i++) {
cout << "t 的第 " << i << " 个元素:" << t[i] << " " << endl;
}
cout << endl << "pop_back()" << endl;
t.pop_back();
for (int i = 0; i < t.size(); i++) {
cout << "t 的第 " << i << " 个元素:" << t[i] << " " << endl;
}
cout << endl << "insert(t.begin(), 100)" << endl;
t.insert(t.begin(), 100);
for (int i = 0; i < t.size(); i++) {
cout << "t 的第 " << i << " 个元素:" << t[i] << " " << endl;
}
cout << endl << "erase(t.begin())" << endl;
t.erase(t.begin());
for (int i = 0; i < t.size(); i++) {
cout << "t 的第 " << i << " 个元素:" << t[i] << " " << endl;
}
t.swap(v);
cout << endl << "t.swap(v)" << endl;
for (int i = 0; i < t.size(); i++) {
cout << "t 的第 " << i << " 个元素:" << t[i] << " " << endl;
}
return 0;
}
输出:
v 的第 0 个元素:41
v 的第 1 个元素:18467
v 的第 2 个元素:6334
v 的第 3 个元素:26500
v 的第 4 个元素:19169
v 的第 5 个元素:15724
v 的第 6 个元素:11478
v 的第 7 个元素:29358
v 的第 8 个元素:26962
v 的第 9 个元素:24464
vector.size() = 10
vector.max_size() = 1073741823
vector.capacity() = 10
vector.empty() = 0
vector.at(0) = 41
vector.front() = 41
vector.back() = 24464
vector.data() = 00FF3580
change size and capacity
vector.size() = 5
vector.capacity() = 100
降低其容量和 size 匹配
vector.size() = 5
vector.capacity() = 5
assign的第一种用法
t 的第 0 个元素:41
t 的第 1 个元素:18467
t 的第 2 个元素:6334
t 的第 3 个元素:26500
t 的第 4 个元素:19169
assign的第二种用法
t 的第 0 个元素:1
t 的第 1 个元素:1
t 的第 2 个元素:1
t 的第 3 个元素:1
t 的第 4 个元素:1
t 的第 5 个元素:1
t 的第 6 个元素:1
t 的第 7 个元素:1
t 的第 8 个元素:1
t 的第 9 个元素:1
push_back(100)
t 的第 0 个元素:1
t 的第 1 个元素:1
t 的第 2 个元素:1
t 的第 3 个元素:1
t 的第 4 个元素:1
t 的第 5 个元素:1
t 的第 6 个元素:1
t 的第 7 个元素:1
t 的第 8 个元素:1
t 的第 9 个元素:1
t 的第 10 个元素:100
pop_back()
t 的第 0 个元素:1
t 的第 1 个元素:1
t 的第 2 个元素:1
t 的第 3 个元素:1
t 的第 4 个元素:1
t 的第 5 个元素:1
t 的第 6 个元素:1
t 的第 7 个元素:1
t 的第 8 个元素:1
t 的第 9 个元素:1
insert(t.begin(), 100)
t 的第 0 个元素:100
t 的第 1 个元素:1
t 的第 2 个元素:1
t 的第 3 个元素:1
t 的第 4 个元素:1
t 的第 5 个元素:1
t 的第 6 个元素:1
t 的第 7 个元素:1
t 的第 8 个元素:1
t 的第 9 个元素:1
t 的第 10 个元素:1
erase(t.begin())
t 的第 0 个元素:1
t 的第 1 个元素:1
t 的第 2 个元素:1
t 的第 3 个元素:1
t 的第 4 个元素:1
t 的第 5 个元素:1
t 的第 6 个元素:1
t 的第 7 个元素:1
t 的第 8 个元素:1
t 的第 9 个元素:1
t.swap(v)
t 的第 0 个元素:41
t 的第 1 个元素:18467
t 的第 2 个元素:6334
t 的第 3 个元素:26500
t 的第 4 个元素:19169