好的!既然你提到了 C++ 标准库中的容器适配器 <queue>
,我将为你详细讲解它的用法,包括基本概念、特性、功能以及实用示例。<queue>
是 C++ STL 中的一种队列容器适配器,遵循“先进先出”(FIFO, First In First Out)的原则。它基于底层容器(如 <deque>
)实现,提供简洁的队列操作接口。以下是完整的内容,适合学习和实践。
C++ 标准库:<queue>
<queue>
是一个模板类,封装了队列的行为。它的主要特点是:
- FIFO 结构:元素按先进先出的顺序访问。
- 适配器设计:基于底层容器(如
<deque>
、<list>
)实现。 - 简单接口:仅提供队首和队尾操作。
- 动态大小:大小随元素增减动态调整。
包含头文件
#include <queue>
#include <iostream> // 通常配合使用
定义格式
std::queue<类型, 底层容器> 变量名;
类型
:队列中元素的数据类型(如int
、double
、std::string
)。底层容器
:可选,默认是std::deque<T>
,也可以指定为std::list<T>
(<vector>
不适用,因不支持pop_front()
)。
基本用法
1. 声明和初始化
#include <queue>
#include <iostream>
int main() {
std::queue<int> q; // 默认使用 deque 作为底层容器
q.push(1); // 入队
q.push(2);
q.push(3);
std::cout << "Front: " << q.front() << std::endl; // 输出:1
return 0;
}
- 不支持直接用初始化列表,需逐个
push
。
2. 入队和出队
#include <queue>
#include <iostream>
int main() {
std::queue<int> q;
q.push(10); // 入队
q.push(20);
q.push(30);
std::cout << "Front: " << q.front() << std::endl; // 输出:10
q.pop(); // 出队
std::cout << "After pop: " << q.front() << std::endl; // 输出:20
return 0;
}
push()
:O(1),将元素加入队尾。pop()
:O(1),移除队首元素(不返回)。
3. 访问队首和队尾
#include <queue>
#include <iostream>
int main() {
std::queue<std::string> q;
q.push("Apple");
q.push("Banana");
std::cout << "Front: " << q.front() << std::endl; // 输出:Apple
std::cout << "Back: " << q.back() << std::endl; // 输出:Banana
return 0;
}
front()
:O(1),返回队首元素的引用。back()
:O(1),返回队尾元素的引用。- 无随机访问,只能访问首尾。
4. 大小和状态
#include <queue>
#include <iostream>
int main() {
std::queue<int> q;
std::cout << "Empty? " << (q.empty() ? "Yes" : "No") << std::endl; // 输出:Yes
std::cout << "Size: " << q.size() << std::endl; // 输出:0
q.push(1);
q.push(2);
std::cout << "Empty? " << (q.empty() ? "Yes" : "No") << std::endl; // 输出:No
std::cout << "Size: " << q.size() << std::endl; // 输出:2
return 0;
}
empty()
:O(1),检查队列是否为空。size()
:O(1),返回当前元素数。
5. 指定底层容器
#include <queue>
#include <list>
#include <iostream>
int main() {
std::queue<int, std::list<int>> q; // 使用 list 作为底层容器
q.push(10);
q.push(20);
q.push(30);
std::cout << "Front: " << q.front() << std::endl; // 输出:10
q.pop();
std::cout << "New front: " << q.front() << std::endl; // 输出:20
return 0;
}
- 默认用
<deque>
,也可改为<list>
。
与其他容器的对比
特性 | std::queue | std::deque | std::stack |
---|---|---|---|
数据结构 | 队列(FIFO) | 双端队列 | 栈(LIFO) |
访问方式 | 队首/队尾 | 随机访问 | 仅栈顶 |
插入/删除 | 队尾入/队首出 O(1) | 首尾 O(1),其他 O(n) | 仅顶部 O(1) |
底层容器 | 可选(默认 deque) | 自身 | 可选(默认 deque) |
迭代器 | 不支持 | 支持 | 不支持 |
注意事项
- 接口限制:无迭代器,无法遍历所有元素,只能操作队首和队尾。
- 异常安全:
front()
或pop()
在空队列上调用是未定义行为,需先检查empty()
。 - 底层容器选择:
<deque>
(默认):首尾操作高效,随机访问支持。<list>
:插入/删除高效,但内存开销大,无随机访问。<vector>
不适用(无pop_front()
)。
- 性能:依赖底层容器,默认
<deque>
提供最佳平衡。
实用示例:任务处理队列
以下是一个模拟任务处理队列的示例:
#include <queue>
#include <iostream>
#include <string>
int main() {
std::queue<std::string> tasks;
tasks.push("Write code");
tasks.push("Test app");
tasks.push("Deploy");
std::cout << "Processing tasks:\n";
while (!tasks.empty()) {
std::cout << "Processing: " << tasks.front() << "\n";
tasks.pop();
}
std::cout << "All tasks completed.\n";
return 0;
}
输出:
Processing tasks:
Processing: Write code
Processing: Test app
Processing: Deploy
All tasks completed.
小练习
以下是一个基于 <queue>
的练习题,你可以尝试:
问题:
写一个 C++ 程序:
- 定义一个
std::queue<int>
。 - 依次入队 10、20、30、40。
- 输出队首和队尾元素。
- 出队两个元素。
- 输出剩余元素个数和队首元素。
参考答案(你可以先尝试)
#include <queue>
#include <iostream>
int main() {
std::queue<int> q;
// 入队
q.push(10);
q.push(20);
q.push(30);
q.push(40);
// 输出队首和队尾
std::cout << "Front: " << q.front() << std::endl; // 输出:10
std::cout << "Back: " << q.back() << std::endl; // 输出:40
// 出队两个元素
q.pop();
q.pop();
// 输出剩余元素个数和队首
std::cout << "Size: " << q.size() << std::endl; // 输出:2
std::cout << "New front: " << q.front() << std::endl; // 输出:30
return 0;
}
下一步
- 如果你想试试这个练习,请写下你的代码,我会帮你检查。
- 如果你想要更复杂的内容(如优先级队列
<priority_queue>
的介绍、自定义队列行为),或者设计<queue>
的测验题,请告诉我! - 你也可以提出具体问题,如“如何用
<queue>
模拟银行排队?”或“<queue>
和<deque>
的区别?”。
现在,你想做什么?试试练习,还是有其他需求?
发表回复