C++ -- 队列std::queue

C++ 中的队列(Queue)是一种遵循‌先进先出‌(FIFO, First In First Out)原则的线性数据结构。元素从队尾(Rear)进入,从队头(Front)移除。

在 C++ 中,使用队列主要有两种方式:

  1. 使用 STL 标准库 ‌:std::queue(最常用、推荐)。
  2. 手动实现‌:基于数组(循环队列)或链表,用于理解底层原理或特定场景优化。

1. STL std::queue 的使用

std::queue 是一个‌容器适配器 ‌,默认底层使用 std::deque(双端队列)实现,也可以指定为 std::list。它封装了底层容器的操作,只暴露队列特有的接口。

1.1 基本操作

注意 ‌:pop() 函数不返回被删除的元素。如果需要获取并删除队头元素,需先调用 front() 获取值,再调用 pop()

1.2 代码示例
cpp 复制代码
#include <iostream>
#include <queue>
#include <string>

using namespace std;

int main() {
    // 1. 创建队列
    queue<int> q;

    // 2. 入队 (Push)
    q.push(10);
    q.push(20);
    q.push(30);

    // 3. 查看状态
    cout << "队列大小: " << q.size() << endl;       // 输出: 3
    cout << "队头元素: " << q.front() << endl;       // 输出: 10
    cout << "队尾元素: " << q.back() << endl;        // 输出: 30

    // 4. 出队 (Pop) - 注意 pop 没有返回值
    if (!q.empty()) {
        int val = q.front(); // 先获取值
        q.pop();             // 再移除
        cout << "出队元素: " << val << endl;         // 输出: 10
    }

    // 5. 遍历队列 (队列不支持迭代器,只能通过不断出队来遍历,这会破坏队列)
    // 如果需要保留原队列,通常复制一份或使用其他容器
    while (!q.empty()) {
        cout << q.front() << " ";
        q.pop();
    }
    // 输出: 20 30 
    
    return 0;
}
1.3 自定义底层容器

虽然默认使用 deque,但你可以根据需求指定底层容器:

cpp 复制代码
#include <list>
#include <queue>

// 使用 list 作为底层容器(适合频繁插入删除,但内存开销大)
queue<int, list<int>> q_list;

// 使用 deque 作为底层容器(默认,缓存友好,支持随机访问但队列接口屏蔽了该功能)
queue<int, deque<int>> q_deque; 
cpp 复制代码
#include <iostream>
#include <stdexcept>

using namespace std;

template <typename T>
class CircularQueue {
private:
    T* data;
    int front;
    int rear;
    int capacity;

public:
    CircularQueue(int size) : capacity(size + 1), front(0), rear(0) {
        data = new T[capacity];
    }

    ~CircularQueue() {
        delete[] data;
    }

    bool isEmpty() {
        return front == rear;
    }

    bool isFull() {
        return (rear + 1) % capacity == front;
    }

    void push(T val) {
        if (isFull()) {
            throw overflow_error("Queue is full");
        }
        data[rear] = val;
        rear = (rear + 1) % capacity;
    }

    void pop() {
        if (isEmpty()) {
            throw underflow_error("Queue is empty");
        }
        front = (front + 1) % capacity;
    }

    T getFront() {
        if (isEmpty()) {
            throw underflow_error("Queue is empty");
        }
        return data[front];
    }
    
    int size() {
        return (rear - front + capacity) % capacity;
    }
};

// 测试
int main() {
    CircularQueue<int> cq(3); // 实际只能存3个元素,因为预留了一个空间
    cq.push(1);
    cq.push(2);
    cq.push(3);
    
    cout << "Front: " << cq.getFront() << endl; // 1
    cq.pop();
    cout << "Front after pop: " << cq.getFront() << endl; // 2
    
    cq.push(4); // 此时空间复用
    cout << "Size: " << cq.size() << endl; // 3
    
    return 0;
}
相关推荐
重生之后端学习7 分钟前
283. 移动零[简单]✅
开发语言·数据结构·算法·leetcode·职场和发展
动词ing1 小时前
【C语言】结构体+文件基础
c语言·开发语言·数据结构
caimouse1 小时前
ReactOS 窗口系统分析(7):分层窗口与绘制辅助 — layered.c + draw.c
c语言·开发语言
丰锋ff2 小时前
基于 Qt 的智慧社区物业管理系统
开发语言·qt
夜不会漫长2 小时前
C++入门(1)
开发语言·c++·算法
大鹏说大话2 小时前
从爬虫到决策引擎:大数据下自媒体如何用Python挖掘用户痛点
开发语言·爬虫·python
Niuguangshuo2 小时前
silero-vad:超轻量级开源 VAD 实践指南
开发语言·python
哭哭啼3 小时前
JAVA服务问题诊断
java·开发语言·jvm
旖旎夜光4 小时前
LeetCode 852:山脉数组的峰顶索引(二分查找) —— 题解
数据结构·c++·算法·leetcode·二分查找
..Dauntless..4 小时前
【C++】继承——基类和派生类的配合
开发语言·c++·算法