悠悠楠杉
C++如何使用queue(队列):从入门到实战
在现代C++开发中,标准模板库(STL)提供了许多高效且易于使用的容器,其中 queue(队列)是处理“先进先出”(FIFO, First In First Out)逻辑的核心工具之一。无论是在算法题中的广度优先搜索(BFS),还是在实际项目中处理任务调度、消息传递等场景,queue 都扮演着不可或缺的角色。本文将带你深入理解C++中 queue 的基本概念、常用操作以及实际应用示例。
要使用 queue,首先需要包含头文件 <queue>:
cpp
include
queue 并不是一个独立的数据结构,而是对其他底层容器(如 deque 或 list)的封装,它只允许在队尾添加元素,在队首移除元素。这种限制性设计恰恰保证了其行为的清晰和高效。
定义一个 queue 非常简单。例如,创建一个存储整数的队列:
cpp
std::queue<int> q;
你可以通过 push() 方法向队列尾部插入元素,通过 pop() 从队首移除元素。需要注意的是,pop() 并不返回被移除的值,若想获取队首元素,应先调用 front(),再调用 pop()。同样,back() 可以访问队尾元素。例如:
cpp
q.push(10);
q.push(20);
q.push(30);
std::cout << "队首元素: " << q.front() << std::endl; // 输出 10
std::cout << "队尾元素: " << q.back() << std::endl; // 输出 30
q.pop(); // 移除队首元素
std::cout << "新的队首: " << q.front() << std::endl; // 输出 20
判断队列是否为空应使用 empty() 函数,而 size() 返回当前元素个数。切记不要在空队列上调用 front() 或 back(),否则会导致未定义行为。
cpp
if (!q.empty()) {
std::cout << "队列大小: " << q.size() << std::endl;
}
queue 的典型应用场景之一是实现广度优先搜索。比如在一个迷宫问题中,我们需要从起点开始逐层探索相邻节点。这时,queue 能自然地维护待访问的节点顺序:
cpp
include
include
include
struct Point {
int x, y;
Point(int x, int y) : x(x), y(y) {}
};
int main() {
std::queue
bfsQueue.push(Point(0, 0));
while (!bfsQueue.empty()) {
Point p = bfsQueue.front();
bfsQueue.pop();
std::cout << "访问点: (" << p.x << ", " << p.y << ")" << std::endl;
// 模拟扩展上下左右四个方向
if (p.x < 2) bfsQueue.push(Point(p.x + 1, p.y));
if (p.y < 2) bfsQueue.push(Point(p.x, p.y + 1));
}
return 0;
}
此外,queue 常用于模拟现实世界中的排队系统,如打印任务队列、客户等待服务等。假设有一个简单的银行叫号系统:
cpp
std::queue
customerQueue.push("张三");
customerQueue.push("李四");
customerQueue.push("王五");
while (!customerQueue.empty()) {
std::cout << "请 " << customerQueue.front() << " 到1号窗口办理业务" << std::endl;
customerQueue.pop();
}
值得一提的是,queue 是一个容器适配器,默认底层使用 deque,但也可以指定 list 或 vector(不过 vector 不支持 pop_front,因此不能作为 queue 的底层容器)。自定义底层容器的方式如下:
cpp
std::queue<int, std::list<int>> q_list; // 使用 list 作为底层容器
虽然 queue 接口简洁,但功能受限——你无法遍历它,也无法随机访问中间元素。这正是它的设计哲学:通过限制操作来确保语义清晰和安全性。如果你需要更多灵活性,可能要考虑 deque 或 list。
总之,std::queue 是C++ STL中一个轻量、安全且高效的容器适配器,特别适合处理需要严格遵循“先进先出”原则的场景。掌握它的基本操作和适用范围,能显著提升代码的可读性和健壮性。无论是刷题还是工程开发,它都是值得熟练掌握的工具之一。
