是什么
📚 <vector> 是 C++ 的“会自动变长的数组”。普通数组的大小在编译时就定死了,而 vector 能随时添加、删除元素,并在容量不够时自动扩容。
💡 生活比喻:vector 就像一列连续的长凳。刚开始只坐了 3 个人,后面来了新同学就自动往后加椅子;只要知道座位号(下标),一步就能走到对应位置。但如果在队伍中间插入或删掉一个人,后面所有人都得挪位置。
⚠️ 核心特点:元素在内存中连续存放,支持随机访问;尾部增删快,中间增删慢。
vector<T> —— 创建动态数组
🎯 功能:声明一个类型为 T 的 vector。可以用空构造、指定长度、指定长度和初值,或直接用初始化列表。
💡 比喻:就像租房子——可以租空房、租 5 间空房、租 5 间都配好家具的房子,也可以直接拎包入住精装房。
🔧 常见形式:vector<T> v; / vector<T> v(n); / vector<T> v(n, val); / vector<T> v = {a, b, c};
↩️ 说明:构造完成后 v.size() 返回当前元素个数;不指定初值时,内置类型会被默认初始化(例如 0)。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v1;
vector<int> v2(5);
vector<int> v3(5, 10);
vector<int> v4 = {1, 2, 3, 4};
cout << "v4 size = " << v4.size() << endl;
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v1; // 空 vector
vector<int> v2(5); // 5 个元素,默认值 0
vector<int> v3(5, 10); // 5 个元素,都是 10
vector<int> v4 = {1, 2, 3, 4}; // 初始化列表(C++11)
cout << "v4 size = " << v4.size() << endl; // 4
return 0;
}
push_back(x) —— 在末尾添加元素
🎯 功能:接受一个元素 x,把它复制到 vector 的末尾。如果当前容量不够,会自动扩容。
💡 比喻:就像在队伍最后面新增一把椅子,让新同学坐下。大多数时候非常快,但偶尔椅子不够用了,需要把所有人搬到更大的场地(扩容)。
🔧 声明:void push_back(const T& x);
↩️ 返回值:无返回值。扩容后 size() 增加 1。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
v.push_back(40);
for (int x : v) cout << x << " ";
cout << endl;
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
v.push_back(40); // 末尾添加 40
// v 变成 {10, 20, 30, 40}
for (int x : v) cout << x << " ";
cout << endl;
return 0;
}
pop_back() —— 删除末尾元素
🎯 功能:删掉 vector 的最后一个元素,不需要参数。调用前请确保 vector 非空。
💡 比喻:就像把队伍最后一把椅子撤掉,上面坐的人离场。这个动作只影响队尾,其他人纹丝不动。
🔧 声明:void pop_back();
↩️ 返回值:无返回值。size() 减少 1,容量通常不变。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
v.pop_back();
for (int x : v) cout << x << " ";
cout << endl;
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
v.pop_back(); // 删除末尾的 30
// v 变成 {10, 20}
for (int x : v) cout << x << " ";
cout << endl;
return 0;
}
size() / empty() —— 查个数、判空
🎯 功能:size() 返回当前元素个数;empty() 在个数为 0 时返回 true。
💡 比喻:size() 就像数队伍里有多少人;empty() 就像看队伍是不是空荡荡。
🔧 声明:size_t size() const; bool empty() const;
↩️ 返回值:size() 返回元素个数;empty() 返回是否为空。两者都是 O(1)。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v;
cout << "开始时为空?" << (v.empty() ? "是" : "否") << endl;
v.push_back(1);
v.push_back(2);
cout << "元素个数:" << v.size() << endl;
cout << "现在为空?" << (v.empty() ? "是" : "否") << endl;
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v;
cout << "开始时为空?" << (v.empty() ? "是" : "否") << endl;
v.push_back(1);
v.push_back(2);
cout << "元素个数:" << v.size() << endl; // 2
cout << "现在为空?" << (v.empty() ? "是" : "否") << endl;
return 0;
}
clear() —— 清空所有元素
🎯 功能:删除 vector 中的所有元素,让它变成空 vector。
💡 比喻:就像一键清空收纳盒,把所有东西拿出来扔掉,盒子本身还在。
🔧 声明:void clear();
↩️ 返回值:无返回值。size() 变为 0,容量通常不变。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
v.clear();
cout << "清空后 size = " << v.size() << endl;
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
v.clear(); // 清空
cout << "清空后 size = " << v.size() << endl; // 0
return 0;
}
operator[] / at(i) —— 访问第 i 个元素
🎯 功能:v[i] 和 v.at(i) 都返回第 i 个元素的引用。下标从 0 开始。
💡 比喻:就像凭座位号找人。v[i] 是“直接喊座位号”,喊错了可能出乱子;at(i) 是“先核对座位号在不在范围内”,错了会安全地报错。
🔧 声明:T& operator[](size_t i); T& at(size_t i);
↩️ 返回值:返回对应位置的元素引用,可以读取也可以修改。at 越界会抛出 out_of_range 异常。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
cout << "v[0] = " << v[0] << endl;
cout << "v.at(1) = " << v.at(1) << endl;
v[2] = 99;
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
cout << "v[0] = " << v[0] << endl; // 10
cout << "v.at(1) = " << v.at(1) << endl; // 20
v[2] = 99; // 修改元素
// v = {10, 20, 99}
return 0;
}
front() / back() —— 访问首尾元素
🎯 功能:front() 返回第一个元素,back() 返回最后一个元素。
💡 比喻:就像直接看队伍最前面和最后面的人,不用数下标。
🔧 声明:T& front(); T& back();
↩️ 返回值:分别返回首元素和尾元素的引用。调用前请确保 vector 非空。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
cout << "首元素:" << v.front() << endl;
cout << "尾元素:" << v.back() << endl;
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
cout << "首元素:" << v.front() << endl; // 10
cout << "尾元素:" << v.back() << endl; // 30
return 0;
}
insert(pos, x) —— 在指定位置插入元素
🎯 功能:在迭代器 pos 指向的位置之前插入元素 x。位置通常用 begin() + i 表示。
💡 比喻:就像让新同学插队到第 i 个位置,后面所有人都要向后挪一位,所以中间插入比较慢。
🔧 声明:iterator insert(iterator pos, const T& x);
↩️ 返回值:返回指向新插入元素的迭代器。中间插入的时间复杂度是 O(n)。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
v.insert(v.begin() + 1, 15);
for (int x : v) cout << x << " ";
cout << endl;
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
v.insert(v.begin() + 1, 15); // 在下标 1 处插入 15
// v 变成 {10, 15, 20, 30}
for (int x : v) cout << x << " ";
cout << endl;
return 0;
}
erase(pos) —— 删除指定位置元素
🎯 功能:删除迭代器 pos 指向的元素。也可写成 erase(first, last) 删除一个区间。
💡 比喻:就像让队伍中某个人离开,后面的人都要向前补位,所以中间删除也比较慢。
🔧 声明:iterator erase(iterator pos); iterator erase(iterator first, iterator last);
↩️ 返回值:返回被删除元素下一个位置的迭代器。删除单个元素的时间复杂度是 O(n)。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30, 40};
v.erase(v.begin() + 1);
for (int x : v) cout << x << " ";
cout << endl;
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30, 40};
v.erase(v.begin() + 1); // 删除下标 1 的元素 20
// v 变成 {10, 30, 40}
for (int x : v) cout << x << " ";
cout << endl;
return 0;
}
resize(n) / resize(n, val) —— 改变元素个数
🎯 功能:resize(n) 把 vector 变成 n 个元素;新增元素默认初始化,也可指定为 val。若 n 小于当前大小,多余元素会被删除。
💡 比喻:就像重新调整队伍长度:人不够就拉几个占位,人多了就把后面的裁掉。
🔧 声明:void resize(size_t n); void resize(size_t n, const T& val);
↩️ 返回值:无返回值。时间复杂度与新增/删除元素个数成正比。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
v.resize(5);
v.resize(7, 8);
v.resize(2);
for (int x : v) cout << x << " ";
cout << endl;
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
v.resize(5); // {10, 20, 30, 0, 0}
v.resize(7, 8); // {10, 20, 30, 0, 0, 8, 8}
v.resize(2); // {10, 20}
for (int x : v) cout << x << " ";
cout << endl;
return 0;
}
reserve(n) / capacity() —— 预留空间与当前容量
🎯 功能:reserve(n) 提前分配至少能容纳 n 个元素的空间;capacity() 返回当前容量(不移动元素的前提下最多能装多少)。
💡 比喻:就像提前租一个更大的场地,但场上实际坐多少人由 size() 决定。这样可以避免每次来人都换场地(扩容)。
🔧 声明:void reserve(size_t n); size_t capacity() const;
↩️ 返回值:reserve 无返回值;capacity() 返回当前容量。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v;
v.reserve(100);
cout << "容量:" << v.capacity() << ",元素数:" << v.size() << endl;
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v;
v.reserve(100);
cout << "容量:" << v.capacity() << ",元素数:" << v.size() << endl;
// 容量 >= 100,size = 0
return 0;
}
begin() / end() —— 迭代器
🎯 功能:begin() 返回指向第一个元素的迭代器;end() 返回指向“最后一个元素之后”的迭代器,常用于遍历。
💡 比喻:迭代器就像队伍里的引导员:begin() 站在第一个人前面,end() 站在最后一个人后面,两个引导员之间的就是所有成员。
🔧 声明:iterator begin(); iterator end();
↩️ 返回值:返回对应位置的迭代器。对空 vector,begin() == end()。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
for (auto it = v.begin(); it != v.end(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
for (auto it = v.begin(); it != v.end(); ++it) {
cout << *it << " "; // 10 20 30
}
cout << endl;
return 0;
}
三种常用遍历方式
方式一:下标遍历——最直观,适合需要知道位置的场景。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
for (size_t i = 0; i < v.size(); i++) {
cout << "v[" << i << "] = " << v[i] << endl;
}
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
for (size_t i = 0; i < v.size(); i++) {
cout << "v[" << i << "] = " << v[i] << endl;
}
return 0;
}
方式二:范围 for(C++11,推荐)——简洁,不需要手动管理下标。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
for (int x : v) {
cout << x << " ";
}
cout << endl;
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
for (int x : v) {
cout << x << " "; // 10 20 30
}
cout << endl;
return 0;
}
方式三:迭代器遍历——最通用,配合 insert / erase 时使用。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
for (auto it = v.begin(); it != v.end(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v = {10, 20, 30};
for (auto it = v.begin(); it != v.end(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
⚠️ 安全提醒:v[i] 越界访问是未定义行为,可能导致崩溃或奇怪结果;需要边界检查时优先用 v.at(i)。另外,插入/删除元素可能使已有迭代器失效,不要在遍历过程中随意修改容器。
💡 什么时候用 vector:需要随机访问、主要在尾部增删、数据量会变化时,vector 是首选容器。只在频繁中间插入删除时,才考虑 list 或 deque。
👉下一节:list —— 双向链表 →