C++中的queue容器详解
1. queue概述
queue是C++标准模板库(STL)中的容器适配器,提供先进先出(FIFO)的数据结构功能。queue不是独立容器,而是基于其他容器(如deque、list)实现的适配器。
2. 基本特性
- 先进先出(FIFO):最先插入的元素最先移除
- 容器适配器:基于其他序列容器实现
- 限制访问:只允许访问队首和队尾元素
- 高效操作 :
push和pop操作都是O(1)O(1)O(1)时间复杂度 - 默认实现 :默认使用
deque作为底层容器
3. 头文件与声明
cpp
#include <queue>
using namespace std;
queue<int> q1; // 默认基于deque的整型队列
queue<string, list<string>> q2; // 基于list的字符串队列
queue<double> q3(q1); // 拷贝构造
4. 构造函数与初始化
4.1 默认构造
cpp
queue<int> nums; // 创建空队列
4.2 基于其他容器构造
cpp
deque<int> dq = {1, 2, 3};
queue<int> q(dq); // 使用deque初始化队列
4.3 指定底层容器类型
cpp
queue<string, list<string>> words; // 使用list作为底层容器
5. 容量操作
5.1 empty()
cpp
if (q.empty()) {
cout << "队列为空";
}
5.2 size()
cpp
cout << "队列大小: " << q.size();
6. 元素访问
6.1 front()
cpp
if (!q.empty()) {
cout << "队首元素: " << q.front();
}
6.2 back()
cpp
if (!q.empty()) {
cout << "队尾元素: " << q.back();
}
7. 修改操作
7.1 push()
cpp
q.push(10); // 在队尾插入元素
q.push(20);
q.push(30);
7.2 emplace()
cpp
q.emplace(40); // 在队尾构造元素(避免拷贝)
7.3 pop()
cpp
if (!q.empty()) {
q.pop(); // 移除队首元素(不返回)
}
7.4 swap() (C++11)
cpp
queue<int> q2;
q.swap(q2); // 交换两个队列的内容
8. 完整示例
cpp
#include <iostream>
#include <queue>
#include <list>
using namespace std;
int main() {
// 创建基于list的队列
queue<int, list<int>> q;
// 插入元素
q.push(10);
q.push(20);
q.emplace(30); // 等同于push但效率更高
// 查看队列信息
cout << "队列大小: " << q.size() << endl;
cout << "队首元素: " << q.front() << endl;
cout << "队尾元素: " << q.back() << endl;
// 移除元素
cout << "\n处理元素: ";
while (!q.empty()) {
cout << q.front() << " ";
q.pop();
}
cout << endl;
// 检查队列是否为空
cout << "队列是否为空: " << (q.empty() ? "是" : "否") << endl;
// 使用其他容器初始化队列
list<int> lst = {1, 2, 3, 4, 5};
queue<int, list<int>> q2(lst);
cout << "\n新队列内容: ";
while (!q2.empty()) {
cout << q2.front() << " ";
q2.pop();
}
cout << endl;
return 0;
}
9. 底层容器选择
queue可以基于以下几种容器实现:
deque(默认):综合性能好,两端操作高效list:在任何位置插入删除都高效,但内存不连续
注意:**不能使用vector**作为queue的底层容器,因为vector没有高效的pop_front操作
cpp
// 基于不同容器的队列声明
queue<int> q1; // 默认基于deque
queue<int, list<int>> q2; // 基于list
10. 实际应用示例
10.1 广度优先搜索(BFS)
cpp
void BFS(vector<vector<int>>& graph, int start) {
vector<bool> visited(graph.size(), false);
queue<int> q;
q.push(start);
visited[start] = true;
while (!q.empty()) {
int current = q.front();
q.pop();
cout << "访问节点: " << current << endl;
for (int neighbor : graph[current]) {
if (!visited[neighbor]) {
visited[neighbor] = true;
q.push(neighbor);
}
}
}
}
10.2 打印二进制数
cpp
void printBinaryNumbers(int n) {
queue<string> q;
q.push("1");
for (int i = 1; i <= n; ++i) {
string current = q.front();
q.pop();
cout << current << " ";
q.push(current + "0");
q.push(current + "1");
}
}
11. 性能考虑
-
时间复杂度:
push(): O(1)O(1)O(1)pop(): O(1)O(1)O(1)front(): O(1)O(1)O(1)back(): O(1)O(1)O(1)empty(): O(1)O(1)O(1)size(): O(1)O(1)O(1) (某些实现可能是O(n)O(n)O(n))
-
空间复杂度:取决于底层容器实现
-
底层容器选择影响:
deque通常是平衡的选择list有额外指针开销但更灵活
12. 注意事项
- 调用
front()、back()或pop()前必须检查队列是否为空 queue不提供迭代器,无法遍历队列内元素- 不能使用
vector作为底层容器 - C++11开始支持
emplace()和swap()操作
13. queue与其他容器比较
| 特性 | queue |
deque |
list |
|---|---|---|---|
| 访问方式 | 仅队首和队尾 | 随机访问 | 顺序访问 |
| 插入位置 | 仅队尾 | 两端 | 任意位置 |
| 删除位置 | 仅队首 | 两端 | 任意位置 |
| 迭代器支持 | 不支持 | 支持 | 支持 |
| 内存布局 | 依赖底层容器 | 分段连续 | 非连续 |