基于VECTOR的双端队列

本文档介绍了如何使用C++标准库中的VECTOR实现双端队列,包括头部和尾部的插入与删除操作。通过定义DoubleQueue类,利用front和rear指针管理队列状态,并提供了初始化、入队、出队、获取头部和尾部元素等方法。代码实现了队列满和空的判断,并在主函数中进行了测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于VECTOR的双端队列

题目

1、实现双端队列的插入和删除操作并验证(课本88页);

浅析

什么是双端队列?

双端队列可以在队列的两边进行操作,算法具体细分为头部入队、头部出队、尾部入队、尾部出队等等。

实现思路?

我以Vector向量作为底层数据结构去实现双端队列。

设置front、rear两个标记去进行判别

front指向对列头部第一个数据的位置

rear指向队尾元素的侠义个位置 也就是下一个入队的位置

image-20210929114303315

Vector

vector.assign(capacity,0);

相当于初始化一个数组,其容量为capacity.

代码

DoubleQueue.h

/*
*双端队列
*/

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

const int QueueSize=5;

class DoubleQueue
{
private:
    /* data */
    int front;  //front指向对列头部第一个数据的位置
    int rear;   //指向队尾元素的侠义个位置 也就是下一个入队的位置
    int capacity;   //容量
    vector<int> arr;
public:
    DoubleQueue(int k); //k为大小
    ~DoubleQueue();
    void EnQueueHead(int x);
    void EnQueueTail(int x);
    int DeQueueHead();
    int DeQueueTail();
    int GetHead();
    int GetTail();
    bool IsEmpty();
    bool IsFull();
};

DoubleQueue.cpp

#include"DoubleQueue.h"

DoubleQueue::DoubleQueue(int k)
{
    //初始化空队列
    capacity=k+1;   //浪费一个位置
    arr.assign(capacity,0);
    cout<<"初始化一个容量为"<<capacity<<",实际可存储"<<capacity-1<<"个数据的的双端队列"<<endl;
    front=0;
    rear=0;
}

DoubleQueue::~DoubleQueue()
{
    cout<<"析构"<<endl;
}

void DoubleQueue::EnQueueHead(int x)
{
    //先判断队列是否已满
    if(IsFull())
    {
        cout<<"队列已满"<<endl;
        return;
    }
    front=(front-1+capacity)%capacity;
    arr[front]=x;
    cout<<"头部插入成功"<<endl;
}

void DoubleQueue::EnQueueTail(int x)
{
    //先判断队列是否已满
    if(IsFull())
    {
        cout<<"队列已满"<<endl;
        return;
    }
    arr[rear]=x;
    rear=(rear+1)%capacity;
    cout<<"队尾插入成功"<<endl;
}

int DoubleQueue::DeQueueHead()
{
    //判断队列是否为空
    if(IsEmpty())
    {
        cout<<"队列为空"<<endl;
        return -1;
    }
    //front是第一个元素的位置
    int x=arr[front];
    front=(front+1)%capacity;
    return x;
}

int DoubleQueue::DeQueueTail()
{
    //判断队列是否为空
    if(IsEmpty())
    {
        cout<<"队列为空"<<endl;
        return -1;
    }
    // rear 被设计在数组的末尾,所以要 -1
    int x=arr[(rear - 1 + capacity) % capacity];
    rear=(rear-1+capacity)%capacity;
    return x;
}

int DoubleQueue::GetHead()
{
    //判断队列是否为空
    if(IsEmpty())
    {
        cout<<"队列为空"<<endl;
        return -1;
    }

    return arr[front];
}

int DoubleQueue::GetTail()
{
    //判断队列是否为空
    if(IsEmpty())
    {
        cout<<"队列为空"<<endl;
        return -1;
    }
    // 当 rear 为 0 时防止数组越界
    return arr[(rear - 1 + capacity) % capacity];
}

bool DoubleQueue::IsEmpty()
{
    return front==rear;
}

bool DoubleQueue::IsFull()
{
    return (rear+1)%capacity==front;
}

测试

main.cpp

#include"DoubleQueue.h"

int main()
{
    DoubleQueue d1(5);
    d1.EnQueueHead(1);
    cout<<"取出当前头部数据为:"<<d1.GetHead()<<endl;
    d1.EnQueueHead(2);
    cout<<"取出当前头部数据为:"<<d1.GetHead()<<endl;
    cout<<"这时的尾部数据为:"<<d1.GetTail()<<endl;
    cout<<"-------------------"<<endl;
    d1.EnQueueTail(3);
    cout<<"这时的尾部数据为:"<<d1.GetTail()<<endl;
    cout<<"-------------"<<endl;
    cout<<"数据:"<<d1.DeQueueHead()<<"从头部出队"<<endl;
    cout<<"这时的队头元素为"<<d1.GetHead()<<endl;
    cout<<"这时的尾部元素为"<<d1.GetTail()<<endl;
    system("pause");
    return 0;
}

运行

image-20210929114535324

课上编写,时间仓促,注释随后补上。

### 关于C++ STL中双端队列(deque)的用法与实现 #### 双端队列简介 `std::deque` 是 C++ 标准模板库(STL)提供的一种容器适配器,支持高效的头部和尾部插入/删除操作。尽管 `std::deque` 提供随机访问迭代器的功能,其内部实现并非连续存储空间[^3]。 #### 主要特性 - **高效头尾操作**:`push_front()` 和 `pop_front()` 的时间复杂度为 O(1),使得 `std::deque` 成为处理频繁两端数据操作的理想选择。 - **动态扩展能力**:类似于 `std::vector`,当容量不足时会自动扩容。 - **随机访问支持**:通过索引可以像数组一样访问任意位置的数据。 #### 实现细节 `std::deque` 的典型实现方式是基于分段缓冲区管理机制。具体来说: - 它维护了一个指向固定大小块指针的数组(称为映射表),这些块用于实际存储元素。 - 映射表本身可能也需要动态增长来适应更多的块需求。 - 这种设计允许在保持常数时间内完成首尾增删的同时还提供了接近于连续内存布局的良好缓存性能[^4]。 以下是简单的代码示例展示如何使用 `std::deque`: ```cpp #include <iostream> #include <deque> int main() { std::deque<int> d {1, 2, 3}; // 插入到前面 d.push_front(0); // 插入到最后面 d.push_back(4); // 遍历并打印所有元素 for(auto it = d.begin(); it != d.end(); ++it){ std::cout << *it << ' '; } std::cout << '\n'; // 删除第一个元素 d.pop_front(); // 删除最后一个元素 d.pop_back(); return 0; } ``` 上述程序创建了一个整型双端队列,并演示了基本的操作方法[^5]。 #### 性能考量 由于 `std::deque` 不同于 `std::vector` 并不保证连续性,在某些情况下可能会带来额外开销比如较差的空间局部性和跨页错误风险增加等问题;然而对于需要频繁执行前后插拔动作的应用场景而言,则往往能够获得更优的整体效率表现[^6]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值