(一)介绍 vector
(1)简介
- 什么是vector?
vector
是一种可以存储任意类型的动态数组,属于序列式容器,底层数据结构是数组,支持随机访问元素。vector
可以在运行时增加或减小其空间大小。 - 使用时注意: 在使用vector时要添加头文件
<vector>
;<vector>
位于命名空间std
中 使用时要添加std::
或在程序开头几行添加using namespace std;
。
(2)特性
- 动态内存:
vector
能够根据需要自动调整其大小,以容纳新添加的元素。这意味着你不需要在编译时知道将要存储多少元素;其空间的增加不是另外添加一片空间,而是寻找一片更大的空间,将原有空间的数据拷贝过去并释放原有空间。 - 随机访问: 由于
vector
在底层使用数组来存储元素,因此它支持高效的随机访问。你可以使用下标运算符[]或at()方法在常数时间内访问任何元素。 - 连续内存:
vector
中的元素在内存中是连续存储的,这使得它能够利用CPU的缓存机制,提高访问速度。同时,这也意味着你可以很容易地将vector
的内容传递给需要连续内存块的函数或算法。 - 高效尾部操作:
vector
的尾部添加或删除元素通常是非常高效的,因为这些操作只需要调整内部指针或分配新的内存块。然而,在vector
的开头或中间插入或删除元素可能会比较费力,因为它们可能需要移动大量的元素。
(二)vector 常用操作
(1)构造函数
-
默认构造函数 创建一个空的
vecotr
容器std::vector<类型> v_1; // 创建一个空的 vecotr 容器
-
填充构造函数
std::vector<类型> v_1(3 , 6); // 创建一个 vecotr 容器 容器中有 3 个 6
-
拷贝构造
std::vector<类型> v_1(3 , 6); // 创建一个 vecotr 容器 容器中有 3 个 6 std::vector<类型> v_2(v_1); // 将v_1 拷贝到v_2
(2)迭代器
-
iterator
- begin() :返回指向容器第一个元素的迭代器。
- end() :返回指向容器末尾之后位置的迭代器。
-
const_iterator
- cbegin() :返回指向容器第一个元素的常量迭代器。
- cend() :返回指向容器末尾之后位置的常量迭代器。
-
reverse_iterator
- rbegin() :返回指向容器最后一个元素的逆向迭代器。
- rend() :返回指向容器第一个元素之前位置的逆向迭代器。
-
const_reverse_iterator
- crbegin() :返回指向容器最后一个元素的常量逆向迭代器。
- crend() :返回指向容器第一个元素之前位置的常量逆向迭代器。
(3)元素访问
-
下标访问: 使用operator[],不进行边界检查,可能引发未定义行为。
-
at()
访问: 使用at()方法,进行边界检查,如果越界会出现std::out_of_range异常。 -
迭代器访问: 使用迭代器(包括begin()和end())遍历vector。
-
示例代码:
- 正向遍历
for (vector<stu>::iterator it = v.begin(); it != v.end(); it++) { stu temp = *it; // 接收it迭代器指向的结构体数据 cout << temp.name << temp.id << endl; }
- 反向遍历
for (vector<stu>::reverse_iterator it = v.rbegin(); it != v.rend(); it++) { stu temp = *it; // 接收it迭代器指向的结构体数据 cout << temp.name << temp.id << endl; }
(4)容量与大小
size()
: 返回vector中元素的数量。empty()
: 检查vector是否为空。capacity()
: 返回vector在不分配更多内存的情况下可以容纳的元素数量。reserve()
: 请求改变容器的容量至少为指定的新大小。shrink_to_fit()
: 请求减少容器的容量以匹配其大小,但不一定成功。
(5)修改
-
push_back()
: 在vector的末尾添加一个元素。 -
pop_back()
: 移除vector的最后一个元素。 -
insert()
: 在指定位置插入一个或多个元素。 -
erase()
: 移除指定位置的元素或范围内的元素。 -
clear()
: 移除所有元素,使vector大小变为0。 -
assign()
: 用指定数量的元素或另一个范围内的元素替换vector的内容。 -
示例代码:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct stu
{
string name;
int id;
stu() {}
stu(string name , int id)
:name(name) , id(id)
{}
};
int main(int argc, char const *argv[])
{
vector<stu> v;
// 插入
// 尾插
v.push_back(stu("张三" , 1));
v.push_back(stu("李四" , 2));
// 获取指向第一个元素的迭代器
vector<stu>::iterator it = v.begin();
// 在 it 位置插入
v.insert(it+2, stu("王五" , 3));
// 遍历
// 正向遍历
for (vector<stu>::iterator it = v.begin(); it != v.end(); it++)
{
stu temp = *it; // 接收it迭代器指向的结构体数据
cout << temp.name << temp.id << endl;
}
cout << endl;
// 删除
// 尾删
v.pop_back();
for (vector<stu>::iterator it = v.begin(); it != v.end(); it++)
{
stu temp = *it; // 接收it迭代器指向的结构体数据
cout << temp.name << temp.id << endl;
}
cout << endl;
// 任意位置删除
it = v.begin();
v.erase(it);
for (vector<stu>::iterator it = v.begin(); it != v.end(); it++)
{
stu temp = *it; // 接收it迭代器指向的结构体数据
cout << temp.name << temp.id << endl;
}
cout << endl;
v.clear(); // 清空
for (vector<stu>::iterator it = v.begin(); it != v.end(); it++)
{
stu temp = *it; // 接收it迭代器指向的结构体数据
cout << temp.name << temp.id << endl;
}
return 0;
}
/*
输出结果:
张三1
李四2
王五3
张三1
李四2
李四2
*/