C++学习笔记(二十五)——vector
一、std::vector
(1)vector
与其适用场景
作用:
std::vector
是 C++ 标准模板库(STL)中的动态数组,它的大小可以动态增长或缩小,并且提供了自动内存管理和丰富的操作函数。
特点:
- 自动管理内存(不需要手动
new/delete
)。 - 动态扩展(不像普通数组需要固定大小)。
- 支持随机访问(
O(1)
复杂度)。 - 丰富的内置函数(插入、删除、查找、排序等)。
适用场景:
- 适用于需要动态增长的数组 。
- 适用于需要快速访问(O(1))的情况 。
- 适用于需要内存自动管理的情况 。
包含头文件
#include <vector>
(2)vector
vs 数组
特性 | vector | 数组 (int arr[] ) |
---|---|---|
大小 | 动态调整 | 固定大小 |
内存管理 | 自动 | 手动管理 |
元素访问 | O(1) | O(1) |
安全性 | at() 提供边界检查 | 访问越界可能崩溃 |
功能 | 具备 insert, erase, sort 等功能 | 需要手写 |
二、std::vector
的创建
函数 | 作用 |
---|---|
vector<T> vec; | 默认构造一个空vector |
vector<T> vec(n); | 创建一个大小为n 的vector ,默认初始化元素 |
vector<T> vec(n, val); | 创建一个大小为n ,值为val 的vector |
vector<T> vec = {val1, val2, ...}; | 使用列表初始化 |
vector<T> vec(other_vec); | 拷贝构造 |
vector<T> vec(other_vec.begin(), other_vec.end()); | 迭代器范围构造 |
(1) 定义 vector
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
void printVector(const vector<int> v)
{
for (int x : v)
{
cout << x << " ";
}
cout << endl;
}
int main() {
vector<int> v1; // 创建空 vector
vector<int> v2(5); // 创建包含 5 个元素的 vector,默认值为 0
vector<int> v3(5, 100); // 创建 5 个 100
vector<int> v4 = {1, 2, 3}; // 直接初始化
vector<int> v5(v4); // 复制另一个 vector
printVector(v1);
printVector(v2);
printVector(v3);
printVector(v4);
printVector(v5);
system("pause");
return 0;
}
(2) 向 vector
添加元素
示例:
#include <iostream>
using namespace std;
#include <vector>
int main() {
vector<int> v;
v.push_back(10); // 添加元素
v.push_back(20);
v.emplace_back(30); // 效率更高
for (int x : v)
{
cout << x << " ";
}
cout << endl;
system("pause");
return 0;
}
注意:
push_back
:先构造一个临时对象,然后拷贝/移动到容器中。emplace_back
:直接在容器的内存空间中构造对象,避免临时对象的创建和拷贝/移动,提高效率。
(3) 访问 vector
元素
函数 | 作用 |
---|---|
vec[i] | 索引访问,无越界检查 |
vec.at(i) | 索引访问,带越界检查(越界抛异常) |
vec.front() | 返回第一个元素 |
vec.back() | 返回最后一个元素 |
vec.data() | 返回指向底层数组的指针 |
示例:
#include <iostream>
using namespace std;
#include <vector>
int main() {
vector<int> v;
v.push_back(10); // 添加元素
v.push_back(20);
v.emplace_back(30); // 效率更高
cout << v[0] << endl; // 直接访问
cout << v.at(1) << endl; // 安全访问,带边界检查
cout << v.front() << endl; // 获取第一个元素
cout << v.back() << endl; // 获取最后一个元素
system("pause");
return 0;
}
三、遍历 vector
(1) 使用 for
循环
示例:
#include <iostream>
using namespace std;
#include <vector>
int main() {
vector<int> v = {10, 20, 30, 40, 50}; // 直接初始化
for (int i = 0; i < v.size(); i++)
{
cout << v[i] << " ";
}
cout << endl;
system("pause");
return 0;
}
(2) 使用范围 for
作用:
- C++11 引入了范围基 for 循环(range-based for loop),用于简洁、直观地遍历容器(如 vector、list、map 等)。
语法:
for (元素类型 变量 : 容器) {
// 操作变量
}
遍历方式:
- 值遍历:
for (auto x : container)
—— 拷贝元素(适用于基本类型)。 - 引用遍历:
for (auto& x : container)
—— 避免拷贝,提高效率。 - 常引用遍历:
for (const auto& x : container)
—— 保护数据,防止修改。
示例:
#include <iostream>
using namespace std;
#include <vector>
int main() {
vector<int> v = {10, 20, 30, 40, 50}; // 直接初始化
for (int x : v)
{
cout << x << " ";
}
cout << endl;
system("pause");
return 0;
}
(3) 使用迭代器
函数 | 作用 |
---|---|
vec.begin() | 返回指向首元素的迭代器 |
vec.end() | 返回指向尾后元素的迭代器 |
vec.rbegin() | 返回指向末元素的反向迭代器 |
vec.rend() | 返回指向首元素前的反向迭代器 |
示例:
#include <iostream>
using namespace std;
#include <vector>
int main() {
vector<int> v = {10, 20, 30, 40, 50}; // 直接初始化
for (auto it = v.begin(); it != v.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
system("pause");
return 0;
}
四、 std::vector
的常用操作
(1) 插入、删除
函数 | 作用 |
---|---|
vec.push_back(val) | 尾部添加元素 |
vec.emplace_back(args...) | 尾部原地构造元素(比push_back 更高效) |
vec.insert(pos, val) | 在pos 位置插入val |
vec.insert(pos, n, val) | 在pos 位置插入n 个val |
vec.insert(pos, first, last) | 在pos 位置插入迭代器范围的元素 |
vec.erase(pos) | 删除pos 位置的元素 |
vec.erase(first, last) | 删除[first, last) 范围内的元素 |
vec.pop_back() | 删除尾部元素 |
vec.clear() | 清空所有元素 |
示例:
#include <iostream>
using namespace std;
#include <vector>
void printVector(vector<int> v)
{
for (auto it = v.begin(); it != v.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
int main() {
vector<int> v = {1, 2, 3, 4};
printVector(v);
// 插入元素
v.insert(v.begin() + 2, 100); // 在索引 2 位置插入 100, (1,2,100,3,4)
printVector(v);
// 删除元素
v.erase(v.begin()); // 删除第一个元素 (2,100,3,4)
printVector(v);
v.erase(v.begin() + 2); // 删除索引 2 处的元素 (2,100,4)
printVector(v);
// 清空 vector
v.clear();
printVector(v);
system("pause");
return 0;
}
(2) vector
的大小
函数 | 作用 |
---|---|
vec.size() | 返回当前元素数量 |
vec.empty() | 判断是否为空 |
vec.capacity() | 返回当前分配的存储容量 |
vec.shrink_to_fit() | 减少capacity 使其等于size |
vec.reserve(n) | 预分配至少n 个元素的空间 |
vec.resize(n) | 调整大小为n ,新元素默认构造 |
vec.resize(n, val) | 调整大小为n ,新元素初始化为val |
示例:
#include <iostream>
using namespace std;
#include <vector>
void printVector(vector<int> v)
{
for (auto it = v.begin(); it != v.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
int main() {
vector<int> v = {1, 2, 3, 4};
cout << v.size() << endl; // 获取元素个数
cout << v.capacity() << endl; // 获取当前容量
cout << v.empty() << endl; // 是否为空
v.resize(10); // 重新设定大小,默认填充 0
printVector(v);
v = {1, 2, 3, 4};
v.resize(10, 5); // 填充 5
printVector(v);
system("pause");
return 0;
}
(3)vector
的排序
函数 | 作用 |
---|---|
vec.size() | 返回当前元素数量 |
sort(vec.begin(), vec.end()) | 排序 |
reverse(vec.begin(), vec.end()) | 逆序 |
find(vec.begin(), vec.end(), val) | 查找元素 |
binary_search(vec.begin(), vec.end(), val) | 二分查找(需排序) |
示例:
#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
void printVector(vector<int> v)
{
for (auto it = v.begin(); it != v.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
int main() {
vector<int> v = { 3, 1, 4, 5, 2 };
printVector(v);
sort(v.begin(), v.end()); // 升序排序
printVector(v);
reverse(v.begin(), v.end()); // 逆序
printVector(v);
system("pause");
return 0;
}
(4) 交换 vector
示例:
#include <iostream>
using namespace std;
#include <vector>
void printVector(vector<int> v)
{
for (auto it = v.begin(); it != v.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
int main() {
vector<int> a = {1, 2, 3};
vector<int> b = {4, 5, 6};
cout << "交换前: " << endl;
printVector(a);
printVector(b);
a.swap(b); // 交换 a 和 b 的内容
cout << "交换后: " << endl;
printVector(a);
printVector(b);
system("pause");
return 0;
}
注意:
a.swap(b);
交换 a 和 b 的所有元素,避免数据拷贝,提高性能。