C++中的queue容器详解

C++中的queue容器详解

1. queue概述

queue是C++标准模板库(STL)中的容器适配器,提供先进先出(FIFO)的数据结构功能。queue不是独立容器,而是基于其他容器(如dequelist)实现的适配器。

2. 基本特性

  • 先进先出(FIFO):最先插入的元素最先移除
  • 容器适配器:基于其他序列容器实现
  • 限制访问:只允许访问队首和队尾元素
  • 高效操作pushpop操作都是O(1)O(1)O(1)时间复杂度
  • 默认实现 :默认使用deque作为底层容器

3. 头文件与声明

cpp 复制代码
#include <queue>
using namespace std;

queue<int> q1;               // 默认基于deque的整型队列
queue<string, list<string>> q2; // 基于list的字符串队列
queue<double> q3(q1);        // 拷贝构造

4. 构造函数与初始化

4.1 默认构造

cpp 复制代码
queue<int> nums; // 创建空队列

4.2 基于其他容器构造

cpp 复制代码
deque<int> dq = {1, 2, 3};
queue<int> q(dq); // 使用deque初始化队列

4.3 指定底层容器类型

cpp 复制代码
queue<string, list<string>> words; // 使用list作为底层容器

5. 容量操作

5.1 empty()

cpp 复制代码
if (q.empty()) {
    cout << "队列为空";
}

5.2 size()

cpp 复制代码
cout << "队列大小: " << q.size();

6. 元素访问

6.1 front()

cpp 复制代码
if (!q.empty()) {
    cout << "队首元素: " << q.front();
}

6.2 back()

cpp 复制代码
if (!q.empty()) {
    cout << "队尾元素: " << q.back();
}

7. 修改操作

7.1 push()

cpp 复制代码
q.push(10);     // 在队尾插入元素
q.push(20);
q.push(30);

7.2 emplace()

cpp 复制代码
q.emplace(40);  // 在队尾构造元素(避免拷贝)

7.3 pop()

cpp 复制代码
if (!q.empty()) {
    q.pop();    // 移除队首元素(不返回)
}

7.4 swap() (C++11)

cpp 复制代码
queue<int> q2;
q.swap(q2);     // 交换两个队列的内容

8. 完整示例

cpp 复制代码
#include <iostream>
#include <queue>
#include <list>
using namespace std;

int main() {
    // 创建基于list的队列
    queue<int, list<int>> q;
    
    // 插入元素
    q.push(10);
    q.push(20);
    q.emplace(30);  // 等同于push但效率更高
    
    // 查看队列信息
    cout << "队列大小: " << q.size() << endl;
    cout << "队首元素: " << q.front() << endl;
    cout << "队尾元素: " << q.back() << endl;
    
    // 移除元素
    cout << "\n处理元素: ";
    while (!q.empty()) {
        cout << q.front() << " ";
        q.pop();
    }
    cout << endl;
    
    // 检查队列是否为空
    cout << "队列是否为空: " << (q.empty() ? "是" : "否") << endl;
    
    // 使用其他容器初始化队列
    list<int> lst = {1, 2, 3, 4, 5};
    queue<int, list<int>> q2(lst);
    
    cout << "\n新队列内容: ";
    while (!q2.empty()) {
        cout << q2.front() << " ";
        q2.pop();
    }
    cout << endl;
    
    return 0;
}

9. 底层容器选择

queue可以基于以下几种容器实现:

  1. deque(默认):综合性能好,两端操作高效
  2. list:在任何位置插入删除都高效,但内存不连续

注意:**不能使用vector**作为queue的底层容器,因为vector没有高效的pop_front操作

cpp 复制代码
// 基于不同容器的队列声明
queue<int> q1;                     // 默认基于deque
queue<int, list<int>> q2;          // 基于list

10. 实际应用示例

10.1 广度优先搜索(BFS)

cpp 复制代码
void BFS(vector<vector<int>>& graph, int start) {
    vector<bool> visited(graph.size(), false);
    queue<int> q;
    q.push(start);
    visited[start] = true;
    
    while (!q.empty()) {
        int current = q.front();
        q.pop();
        cout << "访问节点: " << current << endl;
        
        for (int neighbor : graph[current]) {
            if (!visited[neighbor]) {
                visited[neighbor] = true;
                q.push(neighbor);
            }
        }
    }
}

10.2 打印二进制数

cpp 复制代码
void printBinaryNumbers(int n) {
    queue<string> q;
    q.push("1");
    
    for (int i = 1; i <= n; ++i) {
        string current = q.front();
        q.pop();
        cout << current << " ";
        
        q.push(current + "0");
        q.push(current + "1");
    }
}

11. 性能考虑

  1. 时间复杂度

    • push(): O(1)O(1)O(1)
    • pop(): O(1)O(1)O(1)
    • front(): O(1)O(1)O(1)
    • back(): O(1)O(1)O(1)
    • empty(): O(1)O(1)O(1)
    • size(): O(1)O(1)O(1) (某些实现可能是O(n)O(n)O(n))
  2. 空间复杂度:取决于底层容器实现

  3. 底层容器选择影响

    • deque通常是平衡的选择
    • list有额外指针开销但更灵活

12. 注意事项

  1. 调用front()back()pop()前必须检查队列是否为空
  2. queue不提供迭代器,无法遍历队列内元素
  3. 不能使用vector作为底层容器
  4. C++11开始支持emplace()swap()操作

13. queue与其他容器比较

特性 queue deque list
访问方式 仅队首和队尾 随机访问 顺序访问
插入位置 仅队尾 两端 任意位置
删除位置 仅队首 两端 任意位置
迭代器支持 不支持 支持 支持
内存布局 依赖底层容器 分段连续 非连续
相关推荐
格林威1 分钟前
工业相机图像采集处理:从 RAW 数据到 AI 可读图像,附海康相机 C++实战代码
开发语言·c++·人工智能·数码相机·计算机视觉·c#·工业相机
gaozhiyong08135 分钟前
深度架构拆解:Gemini 3.1 Pro的核心技术突破与国内镜像站实测指南
java·开发语言·jvm·mysql
~无忧花开~7 分钟前
React事件处理全解析
开发语言·前端·javascript·react.js·前端框架
tryCbest14 分钟前
Python之FastAPI 高级特性总结与完整项目实战
开发语言·python·fastapi
wjs202414 分钟前
HTML5 Web SQL 深入解析
开发语言
庞轩px16 分钟前
Java基础概念四连问:==与equals、hashCode约定、接口vs抽象类、深拷贝vs浅拷贝
java·开发语言
海上彼尚18 分钟前
Nuxt4 官网访问来源统计的实现
开发语言·前端·javascript
西门吹牛20 分钟前
RV1126B移植mosquitto并且写C语言调用
c语言·开发语言·json
三*一20 分钟前
mapbox 基于 Turf.js 实现高精度多边形分割(支持带空洞 / 坐标无损)
开发语言·前端·javascript·vue.js·mapbox gl
搞技术的雪中飞22 分钟前
Java Lambda表达式实战讲解:从冗余到高效,解锁开发新姿势
java·开发语言·后端