这三个方法通常处理集合类数据(如 vector, string, 哈希表等)。
以下是它们在 C++ 中的核心区别和用法:
- insert() ------ 插入元素
最通用的方法,用于将一个或多个元素插入到容器的指定位置(对于序列容器如 vector)或直接插入(对于关联容器如 set, map)。
对 vector / string 等:在迭代器位置前插入,后续元素后移。
std::vector<int> v = {1, 2, 3};
v.insert(v.begin() + 1, 99); // 在第二个位置插入99 → {1, 99, 2, 3}
对 set / map:根据键自动排序,只需提供值或键值对。
std::set<int> s = {1, 2};
s.insert(3); // s → {1, 2, 3}(自动排序)
- reserve() ------ 预留空间
只对 vector 和 string 这类连续存储的容器有意义。它的作用是提前分配好内存,以避免在后续添加元素时反复扩容(扩容通常需要复制全部元素,开销很大)。
重要:reserve() 只改变容器的 capacity(容量),不改变 size(实际元素个数)。
效果:如果你知道最终会有 1000 个元素,先用 v.reserve(1000);,那么添加 1000 个元素的过程中只会进行 0 次内存重分配,否则可能要重分配 10 次以上。
std::vector<int> v;
v.reserve(1000); // 预留1000个元素的空间
for (int i = 0; i < 1000; ++i) v.push_back(i); // 不会触发扩容
- assign() ------ 重新赋值
它会清空容器原有的所有内容,然后用新指定的元素替换。可以理解为"先清除,后插入"。
常见用法:
用 n 个 val 填充:
std::vector<int> v = {1, 2, 3};
v.assign(5, 42); // v → {42, 42, 42, 42, 42}
用另一个容器的迭代器区间赋值:
std::vector<int> src = {10, 20, 30};
std::vector<int> dst;
dst.assign(src.begin(), src.end()); // dst → {10, 20, 30}
/************************************************************************************/
1.vector - 动态数组
特点:连续内存,支持随机访问,尾部插入/删除快,中间/头部慢。
适用:需要频繁随机访问,主要在尾部操作。
#include <iostream>
#include <vector>
using namespace std;
int main() {
// 1. 构造与赋值
vector<int> v1; // 空 vector
vector<int> v2(5, 10); // {10,10,10,10,10}
vector<int> v3 = {1, 2, 3, 4, 5}; // 初始化列表
vector<int> v4(v3.begin(), v3.end()); // 迭代器区间构造
v1.assign(3, 7); // {7,7,7}
v1 = {1, 2, 3}; // {1,2,3}
// 2. 容量
cout << "size: " << v1.size() << ", capacity: " << v1.capacity() << endl;
v1.reserve(100); // 预留100个位置
cout << "after reserve, capacity: " << v1.capacity() << endl;
// 3. 访问
v1[0] = 10;
v1.at(1) = 20;
cout << "front: " << v1.front() << ", back: " << v1.back() << endl;
// 4. 尾部插入/删除(高效)
v1.push_back(30); // {10,20,3,30}
v1.emplace_back(40); // {10,20,3,30,40}
v1.pop_back(); // {10,20,3,30}
// 5. 中间插入/删除(低效 O(n))
auto it = v1.begin() + 2;
v1.insert(it, 100); // 在索引2位置插入100
v1.erase(v1.begin()); // 删除第一个元素
// 6. 遍历
cout << "Elements: ";
for (int x : v1) {
cout << x << " ";
}
cout << endl;
// 7. 清空与交换
v1.clear(); // 清空所有元素
cout << "After clear, size: " << v1.size() << endl;
v3.swap(v2); // 交换 v3 和 v2
cout << "v3 after swap: ";
for (int x : v3) cout << x << " "; // {10,10,10,10,10}
cout << endl;
return 0;
}
//任意位置操作
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// 辅助函数:打印 vector 内容
void print(const vector<int>& v, const string& msg = "") {
cout << msg;
for (int x : v) {
cout << x << " ";
}
cout << endl;
}
int main() {
// ========== 1. insert 插入单个元素 ==========
vector<int> v1 = {1, 2, 3, 4, 5};
print(v1, "初始: ");
// 在开头插入 99
v1.insert(v1.begin(), 99);
print(v1, "开头插入99: ");
// 在第三个位置(索引2)插入 88
v1.insert(v1.begin() + 2, 88);
print(v1, "索引2插入88: ");
// 在末尾插入 77
v1.insert(v1.end(), 77);
print(v1, "末尾插入77: ");
cout << endl;
// ========== 2. insert 插入多个相同元素 ==========
vector<int> v2 = {10, 20, 30};
print(v2, "初始: ");
// 在第二个位置插入 3 个 99
v2.insert(v2.begin() + 1, 3, 99);
print(v2, "索引1插入3个99: ");
cout << endl;
// ========== 3. insert 插入另一个容器的区间 ==========
vector<int> v3 = {1, 2, 3};
vector<int> v4 = {100, 200, 300};
print(v3, "v3初始: ");
print(v4, "v4: ");
// 将 v4 的全部元素插入到 v3 的第二个位置
v3.insert(v3.begin() + 1, v4.begin(), v4.end());
print(v3, "v3插入v4后: ");
cout << endl;
// ========== 4. insert 插入初始化列表 ==========
vector<int> v5 = {1, 2, 3};
print(v5, "初始: ");
// 在末尾插入 {10, 20, 30}
v5.insert(v5.end(), {10, 20, 30});
print(v5, "末尾插入列表: ");
cout << endl;
// ========== 5. emplace 直接构造(避免临时对象) ==========
vector<pair<int, string>> v6;
v6.push_back({1, "one"}); // 传统方式:需要临时对象
v6.emplace_back(2, "two"); // 尾部直接构造
// 在开头直接构造 pair
v6.emplace(v6.begin(), 0, "zero");
cout << "emplace 结果: ";
for (const auto& p : v6) {
cout << "(" << p.first << "," << p.second << ") ";
}
cout << endl << endl;
// ========== 6. erase 删除单个元素 ==========
vector<int> v7 = {10, 20, 30, 40, 50, 60};
print(v7, "初始: ");
// 删除第一个元素
v7.erase(v7.begin());
print(v7, "删除第一个: ");
// 删除第三个元素(索引2)
v7.erase(v7.begin() + 2);
print(v7, "删除第三个: ");
// 删除最后一个元素
v7.erase(v7.end() - 1);
print(v7, "删除最后一个: ");
cout << endl;
// ========== 7. erase 删除区间 ==========
vector<int> v8 = {10, 20, 30, 40, 50, 60, 70, 80};
print(v8, "初始: ");
// 删除前3个元素 [begin, begin+3)
v8.erase(v8.begin(), v8.begin() + 3);
print(v8, "删除前3个: ");
// 删除最后2个元素 [end-2, end)
v8.erase(v8.end() - 2, v8.end());
print(v8, "删除最后2个: ");
// 删除中间一段 [begin+1, begin+3)
v8.erase(v8.begin() + 1, v8.begin() + 3);
print(v8, "删除索引1到2: ");
cout << endl;
// ========== 8. erase 返回值(指向被删除元素的下一个位置) ==========
vector<int> v9 = {1, 2, 3, 4, 5, 6};
print(v9, "初始: ");
// 删除所有偶数
auto it = v9.begin();
while (it != v9.end()) {
if (*it % 2 == 0) {
it = v9.erase(it); // erase 返回下一个有效迭代器
} else {
++it;
}
}
print(v9, "删除所有偶数后: ");
cout << endl;
// ========== 9. 组合使用:insert + erase ==========
vector<int> v10 = {1, 2, 3, 4, 5};
print(v10, "初始: ");
// 将第三个元素(索引2)移动到开头
int temp = v10[2];
v10.erase(v10.begin() + 2);
v10.insert(v10.begin(), temp);
print(v10, "将第三个元素移到开头: ");
// 将最后一个元素插入到第二个位置
int last = v10.back();
v10.pop_back(); // 或 v10.erase(v10.end() - 1)
v10.insert(v10.begin() + 1, last);
print(v10, "将最后一个元素插入到第二个位置: ");
return 0;
}
- list - 双向链表
特点:非连续内存,不支持随机访问,任何位置插入/删除都快。
适用:需要频繁在中间插入/删除。
#include <list>
#include <iostream>
int main() {
std::list<int> lst;
// 添加元素
lst.push_back(10);
lst.push_front(5);
lst.push_back(20);
// lst: {5, 10, 20}
// 不支持随机访问(不能写 lst[1])
// 只能通过迭代器访问
for (int x : lst) {
std::cout << x << " ";
}
// 输出:5 10 20
// 在中间插入(O(1) 时间复杂度)
auto it = lst.begin();
++it; // 指向第二个元素(10)
lst.insert(it, 7); // {5, 7, 10, 20}
// 删除元素
lst.remove(10); // 删除所有值为10的节点 → {5, 7, 20}
return 0;
}
- deque - 双端队列
特点:分段连续内存,支持随机访问,头尾插入/删除都快。
适用:需要在头尾两端频繁操作。
#include <deque>
#include <iostream>
int main() {
std::deque<int> dq;
// 两端添加
dq.push_back(20);
dq.push_front(10);
dq.push_back(30);
// dq: {10, 20, 30}
// 支持随机访问
std::cout << dq[1] << std::endl; // 输出 20
// 两端删除
dq.pop_front(); // {20, 30}
dq.pop_back(); // {20}
return 0;
}
- set - 集合(唯一、有序)
特点:元素唯一且自动升序排列。
#include <set>
#include <iostream>
int main() {
std::set<int> s;
// 插入元素
s.insert(5);
s.insert(2);
s.insert(8);
s.insert(5); // 重复,不会插入
// 自动排序
for (int x : s) {
std::cout << x << " ";
}
// 输出:2 5 8
// 查找元素
if (s.find(5) != s.end()) {
std::cout << "Found 5" << std::endl;
}
// 删除元素
s.erase(2); // {5, 8}
return 0;
}
- map - 键值对映射(有序)
特点:每个键唯一,按键自动排序。
#include <map>
#include <iostream>
int main() {
std::map<std::string, int> age;
// 插入键值对
age["Alice"] = 25;
age["Bob"] = 30;
age.insert({"Charlie", 28});
// 访问
std::cout << "Alice's age: " << age["Alice"] << std::endl;
// 遍历(按键排序)
for (const auto& [name, years] : age) {
std::cout << name << ": " << years << std::endl;
}
// 输出:Alice: 25, Bob: 30, Charlie: 28
// 查找
if (age.find("Bob") != age.end()) {
std::cout << "Bob found" << std::endl;
}
return 0;
}
unordered_set - 无序集合
#include <unordered_set>
#include <iostream>
int main() {
std::unordered_set<int> us;
us.insert(5);
us.insert(2);
us.insert(8);
us.insert(5); // 重复无效
// 输出顺序不确定(哈希决定)
for (int x : us) {
std::cout << x << " ";
}
// 可能输出:8 2 5 或其他顺序
return 0;
}
unordered_map - 无序映射
#include <unordered_map>
#include <iostream>
int main() {
std::unordered_map<std::string, int> scores;
scores["Alice"] = 95;
scores["Bob"] = 87;
scores["Charlie"] = 92;
// 遍历(顺序不确定)
for (const auto& [name, score] : scores) {
std::cout << name << ": " << score << std::endl;
}
return 0;
}