C++ STL之queue详解

返回主目录

3 queue

3.1 介绍

队列是一种先进先出的数据结构。

//头文件
#include<queue>
//定义初始化
queue<int> q;

3.2 方法函数

代码含义
q.front()返回队首元素 O ( 1 ) O(1) O(1)
q.back()返回队尾元素 O ( 1 ) O(1) O(1)
q.push(element)尾部添加一个元素element 进队 O ( 1 ) O(1) O(1)
q.pop()删除第一个元素 出队 O ( 1 ) O(1) O(1)
q.size()返回队列中元素个数,返回值类型unsigned int O ( 1 ) O(1) O(1)
q.empty()判断是否为空,队列为空,返回true O ( 1 ) O(1) O(1)

3.3 队列模拟

使用q[]数组模拟队列

hh表示队首元素的下标,初始值为0

tt表示队尾元素的下标,初始值为-1,表示刚开始队列为空

一般来说单调栈和单调队列写法均可使用额外变量 tthh 来进行模拟
如有学习余力可学习 单调队列详解

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int q[N];

int main() {
	int hh = 0,tt = -1;
//	入队 
	q[++tt] = 1;
	q[++tt] = 2; 
//	将所有元素出队 
	while(hh <= tt) {
		int t = q[hh++];
		printf("%d ",t);
	}
	return 0;
 } 

3.4 队列模拟例题

题目链接: https://atcoder.jp/contests/abc247/tasks/abc247_d

#include<bits/stdc++.h>
using namespace std;

using ll = long long ;
using pii = pair<int, int>;
const int N = 250005, mod = 998244353;

int q[N], num[N];

void solve() {
	int qq, hh = 0, tt = -1;
	cin >> qq;
	while(qq--) {
		int op;
		cin >> op;
		int x, c;
		if(op == 1) {
			cin >> x >> c;
			q[++tt] = c;
			num[tt] = x;
		} else {
			cin >> c;
			ll res = 0;
			while(c) {
				if(q[hh] > c) {
					q[hh] -= c;
					res += 1ll * c * num[hh];
					break;
				} else {
					res += 1ll * q[hh] * num[hh];
					c -= q[hh++];
				}
			}
			cout << res << "\n";
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	int t;
	// cin >> t;
	t = 1;
	while(t--)
		solve();
	return 0;
}

如要获取所有内容的PDF文件,请在公众号【行码棋】回复【STL】获取,非常抱歉了。
Update:2023-12-11更新PDF文件

<think>好的,我需要回答用户关于C++ STL queue的详细用法和示例的问题。首先,我得回顾一下用户之前提供的引用内容,确保信息的一致性。用户引用了三篇关于queue的文章,其中包含了示例代码和一些基本操作,比如push、pop、front、back、size、empty等。同时,用户之前的问题还涉及queue和priority_queue的区别,所以可能需要简要对比,但这次的重点是queue本身。 首先,我应该从基本定义开始,说明queue是什么,遵循FIFO原则。然后介绍头文件和初始化方法,确保用户知道如何引入和使用queue。接下来是核心操作,如入队、访问元素、出队、获取大小和判断空等,每个操作都需要对应的示例代码,可能直接引用用户提供的示例或者稍作调整。 用户提供的引用[1]和[2]中有示例代码,我需要整合这些代码,确保语法正确,并解释每个步骤的作用。例如,引用[1]中的代码展示了如何创建队列,添加元素,检查是否为空,获取大小,访问队首和队尾元素,以及遍历队列。需要注意用户提供的代码中可能存在拼写错误或输出错误,比如在引用[1]的代码里,最后的判断队列是否空的时候,输出的是“dui lie bu kongn”,这里可能存在中文拼写错误或者排版问题,可能需要调整或指出正确的输出。 然后,应用场景部分需要引用用户提到的广度优先搜索(BFS),如引用[3]所提到的,可以举一个简单的BFS例子,说明queue在此处的应用。同时,可能还需要提到其他常见场景,比如任务调度、缓冲处理等。 此外,用户可能还希望了解queue的底层实现,比如默认使用deque作为容器适配器,但也可以更换为list或其他符合要求的容器。这一点在引用[2]中提到了使用list初始化queue的例子,需要说明如何通过模板参数更换底层容器。 另外,需要注意用户之前的问题中提到的queue和priority_queue的区别,但本次问题集中在queue上,所以可能不需要深入对比,但可以简要提到queue的FIFO特性,而priority_queue则是按优先级。 最后,确保回答结构清晰,分点列出,每个部分都有对应的代码示例和解释,并参考用户提供的引用内容。同时,生成的相关问题要贴合主题,比如底层实现、应用场景、性能分析等。</think>### C++ STL `queue` 使用指南与示例详解 #### 一、基本定义与头文件 `queue` 是 C++ STL 中基于 **先进先出(FIFO)** 原则的容器适配器,需引入头文件 `<queue>`: ```cpp #include <queue> using namespace std; ``` #### 二、初始化与底层容器 默认使用 `deque` 作为底层容器,但可手动指定其他容器(如 `list`): ```cpp queue<int> q1; // 默认使用 deque queue<int, list<int>> q2; // 使用 list 作为底层容器 ``` --- ### 三、核心操作与示例代码 #### 1. 元素入队:`push()` ```cpp queue<int> q; for (int i = 0; i < 5; i++) { q.push(i); // 插入元素 0,1,2,3,4 } ``` #### 2. 访问队首与队尾元素 - `front()`:获取队首元素(最早插入的元素) - `back()`:获取队尾元素(最后插入的元素) ```cpp cout << "队首元素: " << q.front() << endl; // 输出 0 cout << "队尾元素: " << q.back() << endl; // 输出 4 ``` #### 3. 元素出队:`pop()` ```cpp q.pop(); // 移除队首元素 0 cout << "新队首: " << q.front() << endl; // 输出 1 ``` #### 4. 队列状态检查 - `empty()`:判断队列是否为空 - `size()`:获取队列元素数量 ```cpp if (!q.empty()) { cout << "队列大小: " << q.size() << endl; // 输出 4 } ``` #### 5. 遍历队列 由于 `queue` **没有迭代器**,需通过循环依次弹出元素遍历: ```cpp while (!q.empty()) { cout << q.front() << " "; // 输出 1 2 3 4 q.pop(); } ``` --- ### 四、完整示例代码 结合用户提供的引用[1][^1]和引用[2][^2],整合一个典型用例: ```cpp #include <iostream> #include <queue> using namespace std; int main() { queue<int> q; // 插入元素 for (int i = 0; i < 10; i++) { q.push(i); } // 检查队列状态 if (!q.empty()) { cout << "队列非空,当前大小: " << q.size() << endl; cout << "队尾元素: " << q.back() << endl; // 输出 9 } // 遍历并弹出元素 while (!q.empty()) { cout << q.front() << " "; q.pop(); } cout << endl; if (q.empty()) { cout << "队列已空" << endl; } return 0; } ``` **输出**: ``` 队列非空,当前大小: 10 队尾元素: 9 0 1 2 3 4 5 6 7 8 9 队列已空 ``` --- ### 五、典型应用场景 1. **广度优先搜索(BFS)** 用于层次遍历或无权图的最短路径搜索[^3]。例如二叉树层序遍历: ```cpp void BFS(TreeNode* root) { queue<TreeNode*> q; q.push(root); while (!q.empty()) { TreeNode* node = q.front(); q.pop(); if (node->left) q.push(node->left); if (node->right) q.push(node->right); cout << node->val << " "; } } ``` 2. **任务调度** 按顺序处理请求,如打印任务队列、消息队列等。 --- ### 六、性能与底层实现 - **时间复杂度**:`push()` 和 `pop()` 操作均为 $O(1)$,直接操作队首和队尾。 - **底层容器**:默认使用 `deque`(双端队列),支持高效的前端删除和后端插入[^2]。 --- ### 七、总结表格 | 操作 | 函数 | 时间复杂度 | 描述 | |--------------|------------|------------|---------------------------| | 插入元素 | `push()` | O(1) | 在队尾添加元素 | | 移除元素 | `pop()` | O(1) | 移除队首元素 | | 访问队首 | `front()` | O(1) | 返回最早插入的元素 | | 访问队尾 | `back()` | O(1) | 返回最后插入的元素 | | 队列大小 | `size()` | O(1) | 返回当前元素数量 | | 判空 | `empty()` | O(1) | 检查队列是否为空 | --- ### 相关问题 1. 如何用 `queue` 实现多线程任务调度? 2. `deque` 和 `list` 作为 `queue` 的底层容器有何性能差异? 3. 在 BFS 算法中,`queue` 如何避免重复访问节点?
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行码棋

码字好辛苦,总结好吃力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值