一、队列是什么?
队列(queue)是STL 提供的先进先出(FIFO, First In First Out) 容器适配器,就像排队买票:先进入队列的元素,最先出来。
- 只能在队尾插入元素 ,队头删除元素;
- 不能直接访问队列中间的元素,只能访问队头和队尾;
- 底层默认依赖
deque容器,也可指定list等容器。
二、头文件与定义
1. 必须包含的头文件
#include <queue> // 队列核心头文件
using namespace std; // 简化代码,避免每次写std::
2. 队列定义(声明)
语法:queue<数据类型> 队列名;
// 1. 空队列(最常用)
queue<int> q; // 存储int类型的空队列
queue<string> q_str; // 存储字符串的队列
queue<double> q_double; // 存储浮点数的队列
// 2. 用已有容器初始化队列(了解即可)
#include <vector>
vector<int> vec = {1,2,3};
queue<int> q(vec); // 用vector初始化队列
三、核心函数(高频使用,必记)
1. 插入元素:push ()
-
作用:在队尾添加一个元素
-
语法:
队列名.push(元素值);queue<int> q;
q.push(10); // 队尾插入10 → 队列:10
q.push(20); // 队尾插入20 → 队列:10, 20
q.push(30); // 队尾插入30 → 队列:10, 20, 30
2. 删除元素:pop ()
-
作用:删除队头的第一个元素
-
注意:无返回值,删除前建议判断队列非空
-
语法:
队列名.pop();queue<int> q;
q.push(10);
q.push(20);
q.pop(); // 删除队头10 → 队列:20
3. 访问队头:front ()
-
作用:获取队头元素的值(不删除)
-
语法:
队列名.front();queue<int> q;
q.push(10);
q.push(20);
cout << q.front(); // 输出:10(队头元素)
4. 访问队尾:back ()
-
作用:获取队尾元素的值(不删除)
-
语法:
队列名.back();queue<int> q;
q.push(10);
q.push(20);
cout << q.back(); // 输出:20(队尾元素)
5. 判断队列是否为空:empty ()
-
作用:空队列返回
true,非空返回false -
语法:
队列名.empty();queue<int> q;
cout << q.empty(); // 输出:1(true,空队列)
q.push(10);
cout << q.empty(); // 输出:0(false,非空)
6. 获取队列大小:size ()
-
作用:返回队列中元素的个数
-
语法:
队列名.size();queue<int> q;
q.push(10);
q.push(20);
cout << q.size(); // 输出:2(队列有2个元素)
四、完整示例代码(直接运行)
#include <iostream>
#include <queue> // 队列头文件
using namespace std;
int main() {
queue<int> q; // 定义int类型空队列
// 1. 插入元素(队尾入队)
q.push(5);
q.push(10);
q.push(15);
cout << "队列大小:" << q.size() << endl; // 输出:3
// 2. 访问队头、队尾
cout << "队头元素:" << q.front() << endl; // 输出:5
cout << "队尾元素:" << q.back() << endl; // 输出:15
// 3. 删除队头元素
q.pop();
cout << "删除后队头:" << q.front() << endl; // 输出:10
cout << "删除后大小:" << q.size() << endl; // 输出:2
// 4. 遍历队列(边删除边访问,队列会被清空)
cout << "遍历队列:";
while (!q.empty()) { // 队列非空时循环
cout << q.front() << " "; // 打印队头
q.pop(); // 删除队头,继续遍历下一个
}
// 输出:10 15
return 0;
}
五、常用技巧(避坑 + 便捷用法)
1. 遍历队列的正确方式
队列不支持迭代器 ,不能像数组一样用for循环遍历,只能用while循环 +front()+pop()遍历(遍历后队列会清空):
// 安全遍历(不修改原队列,用临时队列)
queue<int> temp = q; // 复制原队列到临时队列
while (!temp.empty()) {
cout << temp.front() << " ";
temp.pop();
}
2. 存储自定义类型(结构体)
队列可以存自定义结构体,示例:
#include <string>
struct Student {
int id;
string name;
};
queue<Student> q_stu;
// 插入结构体元素
Student s1 = {101, "张三"};
q_stu.push(s1);
// 访问结构体元素
cout << q_stu.front().id << " " << q_stu.front().name;
3. 清空队列
STL 队列没有直接清空的函数,用循环清空:
while (!q.empty()) {
q.pop(); // 逐个删除队头,直到为空
}
六、优先级队列(priority_queue,拓展)
优先级队列是特殊队列 ,元素按优先级排序(默认大顶堆:最大值优先出队),用法和普通队列一致,仅定义不同:
#include <queue>
// 定义优先级队列(默认大顶堆)
priority_queue<int> pq;
pq.push(30);
pq.push(10);
pq.push(20);
cout << pq.top(); // 输出:30(队头是最大值)
pq.pop(); // 删除最大值30
七、必背总结
- 核心函数:
push()(入队)、pop()(出队)、front()(队头)、back()(队尾)、empty()(判空)、size()(大小); - 规则:先进先出,只能操作队头和队尾;
- 遍历:用
while循环 +front()+pop(),临时队列可保留原数据; - 头文件:必须加
#include <queue>。
总结
- 队列是先进先出容器,仅支持队尾入队、队头出队;
- 遍历、清空、自定义类型是高频实用技巧。