STL 容器:queue / set / map
一、queue(队列)
1.1 概述
队列是一种**先进先出(FIFO, First In First Out)**的逻辑数据结构:
-
队尾(back):只能插入新元素
-
队头(front):只能删除元素
-
只能访问首尾两端,无法遍历中间元素
出队 ← front [ 队 列 内 部 ] back ← 入队
许多程序都使用了 queue 容器。queue 容器可以用来表示商场结账队列或服务器上等待执行的数据库事务队列。对于任何需要用 FIFO 准则处理的序列来说,使用 queue 容器适配器都是好的选择。
1.2 底层与头文件
cpp
#include <queue>
std::queue<T>是一个容器适配器 ,默认底层容器为std::deque<T>- 也可以指定
std::list<T>作为底层容器
1.3 创建容器适配器
cpp
#include <iostream>
#include <queue>
#include <list>
using namespace std;
int main()
{
// 创建一个使用list容器作为基础容器的空 vq1 容器适配器
queue<int, list<int>> vq1;
deque<int> d1{1,2,3,4,5,6};
queue<int> vq2(d1);
queue<int> vq3 = vq2;
return 0;
}
1.4 queue 基本用法
cpp
#include <iostream>
#include <queue>
#include <list>
using namespace std;
int main()
{
// 构建一个queue容器适配器
deque<int> d1{ 1, 2, 3, 4, 5 };
queue<int> q1(d1);
// 求存储元素的个数
cout << "\n输出qd容器元素个数:" << q1.size() ;
// 输出qd容器所有元素的值
cout << "\n输出qd容器元素:";
while (!q1.empty()) {
cout << q1.front() << " ";
// 访问过的元素出队列
q1.pop();
}
cout << "\n输出qd容器元素个数:" << q1.size() << endl;
return 0;
}

1.5 核心成员函数速查
| 函数 | 功能 |
|---|---|
push(x) |
将元素 x 入队(尾端插入) |
emplace(args...) |
尾端原地构造元素 |
pop() |
移除队头元素 |
front() |
返回队头元素的引用 |
back() |
返回队尾元素的引用 |
empty() |
判断队列是否为空 |
size() |
返回元素个数 |
swap(other) |
与另一队列交换内容 |
📎 其他成员函数可查阅官方文档:cplusplus.com/reference/queue/queue/
二、set(集合)
2.1 概述
set 是一个有序且不重复的关联容器:
- 元素唯一:不允许出现重复值
- 自动排序:元素按一定顺序排列,默认升序
- 底层实现:红黑树(平衡二叉搜索树)
- 时间复杂度:查找、插入、删除均为 O(log n),与元素个数的对数成比例
- 当游标指向一个已删除的元素时,删除操作无效
这在收集一个数据的具体值的时候是非常有用的。在插入操作和删除操作上比 vector 快,但查找或添加末尾的元素时会有些慢。
2.2 set 创建与使用
cpp
#include <iostream>
#include <set>
#include <string>
using namespace std;
int main()
{
// 创建一个set容器
set<string> mys;
cout << "测试容器mys长度:" << mys.size() << endl;
mys.insert("www.baidu.com");
mys.insert("www.163.com");
mys.insert("www.youdaoyun.com");
cout << "插入后的测试容器mys长度:" << mys.size() << endl;
cout << "\n输出mys容器所有元素:" << endl;
for (auto it = mys.begin(); it != mys.end(); it++) {
cout << *it << endl;
}
return 0;
}

输出的时候,自动进行了排序。
2.3 常用成员函数速查
| 函数 | 功能 |
|---|---|
insert(x) |
插入元素 x |
emplace(args...) |
原地构造并插入 |
erase(x) / erase(it) |
删除元素 |
find(x) |
查找元素,返回迭代器(未找到返回 end()) |
count(x) |
返回出现次数(set 中只能是 0 或 1) |
empty() |
判断是否为空 |
size() |
返回元素个数 |
clear() |
清空所有元素 |
三、map(映射)
3.1 概述
map 是一种**键值对(key-value)**关联容器:
- 每个元素是一个
pair<const Key, T>结构,key 和 value 是两个分量,数据类型可以不同 - 键唯一 :
map不支持重复键,multimap支持重复键 - 自动按键排序:默认升序
- 底层实现:红黑树,与 set 一致
- 提供对 T 类型数据的快速、高效检索
set和map的区别:set的 key 即 value,两者是同一类型;map的 key 和 value 是不同的数据类型,存储在pair结构中。
3.2 map 容器创建与使用
cpp
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
// 创建一个mm容器
map<string, string, greater<string>> mm;
// 直接向mm容器指定位置,构造新键值对
mm.emplace("C语言程序设计", "https://www.baidu.com");
mm.emplace("C++语言程序设计", "https://www.google.com");
cout << "输出mm容器存储的键值对个数为:" << mm.size() << endl;
if (!mm.empty()) {
for (auto iter = mm.begin(); iter != mm.end(); iter++) {
cout << iter->first << "\t" << iter->second << endl;
}
}
cout << endl;
return 0;
}

3.3 核心成员函数速查
| 函数 | 功能 |
|---|---|
insert({k,v}) |
插入键值对 |
emplace(k, v) |
原地构造键值对 |
erase(k) / erase(it) |
删除指定键或迭代器的元素 |
find(k) |
查找键 k,返回迭代器(未找到返回 end()) |
count(k) |
返回键的出现次数(0 或 1) |
operator[k] |
通过键访问/插入 value |
at(k) |
带越界检查的访问(键不存在则抛异常) |
empty() |
判断是否为空 |
size() |
返回键值对个数 |
📎 其他成员函数可查阅官方文档:cplusplus.com/reference/map/map/
四、三者对比总结
| 特性 | queue | set | map |
|---|---|---|---|
| 本质 | 容器适配器 | 关联容器 | 关联容器 |
| 底层数据结构 | deque / list | 红黑树 | 红黑树 |
| 元素组成 | 单一值 | 单一值 | 键值对 pair<K,V> |
| 元素重复 | 允许 | ❌ 不允许 | ❌ 键不允许 |
| 排序方式 | FIFO 顺序 | 自动排序 | 按键自动排序 |
| 能否遍历 | ❌ | ✅ | ✅ |
| 典型场景 | 排队、BFS | 去重有序集合 | 字典、索引 |
| 插入/查找/删除 | O(1) | O(log n) | O(log n) |
