STL之队列详解c++

在 C++ 中,队列(Queue)是一种遵循先进先出(First-In-First-Out,FIFO)原则的数据结构,即最先进入队列的元素会最先被移除。下面将从多个方面详细介绍如何实现和使用队列,包括使用标准库中的 std::queue 以及手动实现一个简单的队列。

下面分别介绍 C++ 标准库 std::queue 以及手动实现队列时常见的函数及其功能、使用示例和复杂度分析。

C++ 标准库 std::queue 中的函数

1. 构造函数
  • 功能:用于创建 std::queue 对象。
  • 示例
#include <iostream>
#include <queue>

int main() {
    // 默认构造函数,创建一个空的队列
    std::queue<int> myQueue;
    return 0;
}
2. empty()
  • 功能:检查队列是否为空,若队列为空则返回 true,否则返回 false
  • 复杂度 O ( 1 ) O(1) O(1)
  • 示例
#include <iostream>
#include <queue>

int main() {
    std::queue<int> myQueue;
    if (myQueue.empty()) {
        std::cout << "队列为空" << std::endl;
    }
    return 0;
}
3. size()
  • 功能:返回队列中元素的数量。
  • 复杂度 O ( 1 ) O(1) O(1)
  • 示例
#include <iostream>
#include <queue>

int main() {
    std::queue<int> myQueue;
    myQueue.push(10);
    myQueue.push(20);
    std::cout << "队列的大小为: " << myQueue.size() << std::endl;
    return 0;
}
4. front()
  • 功能:返回队列中第一个(队首)元素的引用。若队列为空,调用此函数会导致未定义行为。
  • 复杂度 O ( 1 ) O(1) O(1)
  • 示例
#include <iostream>
#include <queue>

int main() {
    std::queue<int> myQueue;
    myQueue.push(10);
    std::cout << "队首元素是: " << myQueue.front() << std::endl;
    return 0;
}
5. back()
  • 功能:返回队列中最后一个(队尾)元素的引用。若队列为空,调用此函数会导致未定义行为。
  • 复杂度 O ( 1 ) O(1) O(1)
  • 示例
#include <iostream>
#include <queue>

int main() {
    std::queue<int> myQueue;
    myQueue.push(10);
    myQueue.push(20);
    std::cout << "队尾元素是: " << myQueue.back() << std::endl;
    return 0;
}
6. push()
  • 功能:在队列的尾部插入一个新元素。
  • 复杂度:平均 O ( 1 ) O(1) O(1)
  • 示例
#include <iostream>
#include <queue>

int main() {
    std::queue<int> myQueue;
    myQueue.push(10);
    myQueue.push(20);
    return 0;
}
7. pop()
  • 功能:移除队列的第一个(队首)元素。若队列为空,调用此函数会导致未定义行为。
  • 复杂度:平均 O ( 1 ) O(1) O(1)
  • 示例
#include <iostream>
#include <queue>

int main() {
    std::queue<int> myQueue;
    myQueue.push(10);
    myQueue.pop();
    if (myQueue.empty()) {
        std::cout << "执行出队操作后,队列为空" << std::endl;
    }
    return 0;
}

1. 使用标准库中的 std::queue

1.1 简介

std::queue 是 C++ 标准库中的一个容器适配器,它基于其他容器(如 std::dequestd::list)实现了队列的基本功能。使用 std::queue 可以方便快捷地实现队列操作,无需手动管理队列的底层数据结构。

1.2 常用操作及示例代码
#include <iostream>
#include <queue>

int main() {
    // 创建一个存储整数的队列
    std::queue<int> myQueue;

    // 入队操作:使用 push() 方法将元素添加到队列尾部
    myQueue.push(10);
    myQueue.push(20);
    myQueue.push(30);

    // 检查队列是否为空:使用 empty() 方法
    if (!myQueue.empty()) {
        // 获取队列的大小:使用 size() 方法
        std::cout << "队列的大小为: " << myQueue.size() << std::endl;

        // 查看队首元素:使用 front() 方法
        std::cout << "队首元素是: " << myQueue.front() << std::endl;

        // 查看队尾元素:使用 back() 方法
        std::cout << "队尾元素是: " << myQueue.back() << std::endl;

        // 出队操作:使用 pop() 方法移除队首元素
        myQueue.pop();
        std::cout << "执行一次出队操作后,队首元素变为: " << myQueue.front() << std::endl;
    }

    return 0;
}
1.3 复杂度分析
  • 入队操作 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)

2. 手动实现一个简单的队列

2.1 实现思路

手动实现队列可以使用数组或链表作为底层数据结构。这里我们使用数组来实现一个固定大小的队列,通过两个指针 frontrear 分别表示队首和队尾的位置。

2.2 代码实现
#include <iostream>
#include <stdexcept>

const int MAX_SIZE = 100;

template <typename T>
class Queue {
private:
    T data[MAX_SIZE];
    int front;
    int rear;
    int size;

public:
    // 构造函数,初始化队列
    Queue() : front(0), rear(0), size(0) {}

    // 判断队列是否为空
    bool empty() const {
        return size == 0;
    }

    // 判断队列是否已满
    bool full() const {
        return size == MAX_SIZE;
    }

    // 入队操作
    void push(const T& value) {
        if (full()) {
            throw std::overflow_error("队列已满,无法入队");
        }
        data[rear] = value;
        rear = (rear + 1) % MAX_SIZE;
        ++size;
    }

    // 出队操作
    void pop() {
        if (empty()) {
            throw std::underflow_error("队列为空,无法出队");
        }
        front = (front + 1) % MAX_SIZE;
        --size;
    }

    // 获取队首元素
    T& frontElement() {
        if (empty()) {
            throw std::underflow_error("队列为空,没有队首元素");
        }
        return data[front];
    }

    const T& frontElement() const {
        if (empty()) {
            throw std::underflow_error("队列为空,没有队首元素");
        }
        return data[front];
    }

    // 获取队列的大小
    int getSize() const {
        return size;
    }
};

int main() {
    Queue<int> myQueue;

    try {
        // 入队操作
        myQueue.push(10);
        myQueue.push(20);
        myQueue.push(30);

        // 输出队列大小
        std::cout << "队列大小: " << myQueue.getSize() << std::endl;

        // 输出队首元素
        std::cout << "队首元素: " << myQueue.frontElement() << std::endl;

        // 出队操作
        myQueue.pop();
        std::cout << "执行一次出队操作后,队首元素变为: " << myQueue.frontElement() << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "异常: " << e.what() << std::endl;
    }

    return 0;
}
2.3 复杂度分析
  • 入队操作 push():时间复杂度为 O ( 1 ) O(1) O(1),因为只需要进行常数级的操作。
  • 出队操作 pop():时间复杂度为 O ( 1 ) O(1) O(1),因为只需要更新队首指针。
  • 获取队首元素 frontElement():时间复杂度为 O ( 1 ) O(1) O(1),因为可以直接访问队首元素。
  • 判断队列是否为空 empty():时间复杂度为 O ( 1 ) O(1) O(1),因为只需要比较队列的大小。
  • 判断队列是否已满 full():时间复杂度为 O ( 1 ) O(1) O(1),因为只需要比较队列的大小。
  • 获取队列大小 getSize():时间复杂度为 O ( 1 ) O(1) O(1),因为可以直接返回队列的大小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值