std::queue(队列)
在 C++ 中,std::queue
是标准模板库(STL)中的容器适配器,遵循**先进先出(FIFO,First In First Out)**的原则。即最先进入队列的元素最先被访问。queue
本质上封装了一个底层容器,并仅提供对队列的特定操作。
1. 基本概念
std::queue
是一个容器适配器,它将底层容器包装为一个队列,并提供了以下操作:
push()
:将元素插入到队列的末尾。pop()
:移除队列头部的元素(注意不会返回该元素)。front()
:返回队列头部的元素,但不删除。back()
:返回队列末尾的元素。empty()
:检查队列是否为空。size()
:返回队列中元素的个数。
2. 队列的声明与初始化
std::queue
默认使用 std::deque
作为底层容器,但你也可以使用 std::list
作为底层容器。
使用默认容器(std::deque
):
#include <iostream>
#include <queue>
int main() {
std::queue<int> q; // 创建一个空队列
q.push(10); // 向队列中插入元素 10
q.push(20); // 向队列中插入元素 20
q.push(30); // 向队列中插入元素 30
std::cout << "Queue front element: " << q.front() << std::endl; // 输出队列头部元素
std::cout << "Queue back element: " << q.back() << std::endl; // 输出队列尾部元素
return 0;
}
使用 std::list
作为底层容器:
#include <iostream>
#include <queue>
#include <list>
int main() {
std::queue<int, std::list<int>> q; // 使用 list 作为底层容器
q.push(1);
q.push(2);
std::cout << "Front element: " << q.front() << std::endl;
std::cout << "Back element: " << q.back() << std::endl;
return 0;
}
3. 常用操作
3.1 push()
向队列末尾添加一个元素。
std::queue<int> q;
q.push(10); // 队列现在包含元素 10
q.push(20); // 队列现在包含元素 10, 20 (10 在队列头部, 20 在末尾)
3.2 pop()
移除队列头部的元素。注意此操作不会返回被移除的元素,如果需要获取该元素,可以先调用 front()
访问。
std::queue<int> q;
q.push(10);
q.push(20);
q.pop(); // 移除队列头部的元素,队列现在只剩下 20
3.3 front()
返回队列头部元素的引用(不删除该元素),可以通过它来访问或修改头部的元素。
std::queue<int> q;
q.push(10);
q.push(20);
int frontElement = q.front(); // 获取队列头部的元素
std::cout << "Front element: " << frontElement << std::endl;
3.4 back()
返回队列尾部元素的引用,和 front()
相似,但它返回的是队列中的最后一个元素。
std::queue<int> q;
q.push(10);
q.push(20);
int backElement = q.back(); // 获取队列尾部的元素
std::cout << "Back element: " << backElement << std::endl;
3.5 empty()
检查队列是否为空,如果为空则返回 true
,否则返回 false
。
std::queue<int> q;
std::cout << std::boolalpha << q.empty() << std::endl; // 输出 true,因为队列为空
3.6 size()
返回队列中元素的个数。
std::queue<int> q;
q.push(10);
q.push(20);
std::cout << "Queue size: " << q.size() << std::endl; // 输出 2
4. 完整示例
以下是一个展示 std::queue
基本操作的完整示例。
#include <iostream>
#include <queue>
int main() {
std::queue<int> q;
// 向队列中插入元素
q.push(10);
q.push(20);
q.push(30);
// 输出队列的大小
std::cout << "Queue size: " << q.size() << std::endl;
// 输出队列的头部和尾部元素
std::cout << "Front element: " << q.front() << std::endl;
std::cout << "Back element: " << q.back() << std::endl;
// 移除队列的头部元素
q.pop();
std::cout << "After pop, new front element: " << q.front() << std::endl;
// 检查队列是否为空
if (!q.empty()) {
std::cout << "Queue is not empty" << std::endl;
}
return 0;
}
输出:
Queue size: 3
Front element: 10
Back element: 30
After pop, new front element: 20
Queue is not empty
5. 使用 std::queue
实现常见问题
5.1 用队列实现 BFS(广度优先搜索)
广度优先搜索(BFS)是一种遍历或搜索树或图的算法,可以使用 std::queue
来实现。
#include <iostream>
#include <queue>
#include <vector>
void bfs(int start, const std::vector<std::vector<int>>& adj) {
std::vector<bool> visited(adj.size(), false);
std::queue<int> q;
visited[start] = true;
q.push(start);
while (!q.empty()) {
int node = q.front();
q.pop();
std::cout << node << " "; // 访问节点
// 遍历当前节点的所有邻居
for (int neighbor : adj[node]) {
if (!visited[neighbor]) {
visited[neighbor] = true;
q.push(neighbor);
}
}
}
}
int main() {
// 创建一个简单的无向图
std::vector<std::vector<int>> adj = {
{1, 2}, // 节点 0 的邻居是 1 和 2
{0, 3, 4}, // 节点 1 的邻居是 0, 3 和 4
{0, 4}, // 节点 2 的邻居是 0 和 4
{1, 5}, // 节点 3 的邻居是 1 和 5
{1, 2, 5}, // 节点 4 的邻居是 1, 2 和 5
{3, 4} // 节点 5 的邻居是 3 和 4
};
bfs(0, adj); // 从节点 0 开始进行广度优先搜索
return 0;
}
输出:
0 1 2 3 4 5
5.2 用队列实现任务调度
队列可以用于模拟任务调度的场景,例如处理一批任务并按顺序执行。
#include <iostream>
#include <queue>
#include <string>
int main() {
std::queue<std::string> tasks;
// 向队列中添加任务
tasks.push("Task 1");
tasks.push("Task 2");
tasks.push("Task 3");
// 按顺序处理任务
while (!tasks.empty()) {
std::cout << "Processing " << tasks.front() << std::endl;
tasks.pop(); // 处理完任务后将其移除
}
return 0;
}
输出:
Processing Task 1
Processing Task 2
Processing Task 3
std::queue
是 C++ 标准模板库中的容器适配器,旨在实现先进先出(FIFO,First In First Out)的队列数据结构。std::queue
本身并不是一个独立的容器,它是一种容器适配器,基于底层容器来实现其功能。std::queue
通过将其他标准容器(如 std::deque
或 std::list
)包装成队列的形式,提供了头部出队、尾部入队的接口。