队列(queue)是 C++ STL 中经典的先进先出(FIFO, First In First Out) 数据结构,元素从队尾入队,从队头出队,全程仅支持两端操作,是解决任务调度、缓冲区管理、广度优先搜索(BFS)等问题的核心工具。


一、核心概念与原理

1. 基本特性

  • 操作规则:先进先出(FIFO)。最先入队的元素,最先出队。
  • 操作位置:
    • 队尾(tail):仅执行入队操作(push)。
    • 队头(front):仅执行出队操作(pop)、获取队头元素。
  • 底层容器:默认使用 deque(双端队列),也可指定 list(注意:vector 不可用)。
  • 不支持迭代器:队列是容器适配器,不支持随机访问,只能通过标准接口操作。

2. 关键成员函数

成员函数功能
push(值)入队:将元素添加到队尾
pop()出队:删除队头元素(不返回值)
front()获取队头元素的引用
back()获取队尾元素的引用
size()返回队列中元素的个数
empty()判断队列是否为空,为空返回 true

二、定义与初始化

使用队列必须包含头文件 <queue>。定义时指定元素类型,默认容器为 deque,也可手动指定底层容器。

1. 基础语法

#include <queue> // 必须包含头文件

// 格式: queue<元素类型, 容器类型> 队列名;
queue<int> q1;          // 最常用:int类型,默认deque容器
queue<char, deque<char>> q2; // 显式指定deque容器
queue<int, list<int>> q3;   // 指定list作为底层容器

2. 代码示例

#include <queue>
#include <iostream>
#include <list>
using namespace std;

int main() {
    // 1. 创建空队列
    queue<int> q;
    
    // 2. 定义不同容器的队列(演示用)
    queue<char> q1;          // 默认deque
    queue<int, list<int>> q4; // 指定list
    
    return 0;
}

三、常用操作实战代码

#include <queue>
#include <iostream>
using namespace std;

int main() {
    // 创建一个int类型的空队列
    queue<int> q;

    // 1. 入队操作 (0,1,2,...,9)
    for (int i = 0; i < 10; i++) {
        q.push(i);
    }

    // 2. 获取队列信息
    cout << "队列的数据个数:" << q.size() << endl;
    cout << "队头元素:" << q.front() << ",队尾元素:" << q.back() << endl;

    // 3. 出队操作 (输出并删除队头元素)
    cout << "出队:" << endl;
    while (!q.empty()) {
        cout << q.front() << " "; // 输出队头
        q.pop();                 // 删除队头
    }
    cout << endl;

    return 0;
}

运行结果

队列的数据个数:10
队头元素:0,队尾元素:9
出队:
0 1 2 3 4 5 6 7 8 9

四、底层容器限制与选择

1. 为什么默认是 deque?

deque 支持在头尾快速插入 / 删除,且支持随机访问,是队列的最佳适配。

2. 容器选择规则

可以作为队列底层容器的类型,必须支持以下操作:

  • front()、back()
  • push_back()、pop_front()

结论:

  • ✅ 可用容器:
    • deque:默认选择,头尾操作高效。
    • list:双向链表,头尾操作稳定,适合大数据量。
  • ❌ 不可用容器:
    • vector:不支持 pop_front(),头部删除效率极低(需移动所有元素),不能用作队列容器。
    • forward_list:不支持 back() 和 pop_back()。
    • array:不支持动态扩容。

五、常见应用场景

1. 广度优先搜索(BFS)

队列是 BFS 的核心数据结构,按层级遍历节点:

// 伪代码:BFS核心逻辑
queue<Node> q;
q.push(root);
while(!q.empty()) {
    Node cur = q.front(); q.pop();
    // 处理当前节点
    for(auto child : cur.children) {
        q.push(child);
    }
}

2. 任务调度

模拟现实世界的排队场景(如打印任务池、消息队列):

queue<string> taskQueue;
taskQueue.push("打印文档A");
taskQueue.push("打印文档B");
// 按顺序处理任务

六、核心总结

核心特性说明
核心规则先进先出(FIFO)
操作口诀push 尾,pop 头,front 取顶,back 取尾
头文件#include <queue>
默认容器deque
容器禁忌vector 不可用(不支持 pop_front)
时间复杂度入队 / 出队 / 获取头尾:均为 O(1)

核心口诀:队列队尾进,队头出;push 入,pop 出,front 取头,back 取尾。

更多推荐