c++用vector实现定长队列

2023-05-16

目录

    • queue实现
    • vector实现

我们可以用queue或vector实现定长队列,但是如果我们有遍历定长队列的需求的话,使用queue不是一个好的选择,因为queue本身不支持直接访问元素。

queue实现

C++中的queue标准库提供了一个简单易用的队列容器,可以用来实现定长队列。下面是一段示例代码:

#include <iostream>
#include <queue>

using namespace std;

int main()
{
    queue<int> q;
    int maxlen = 5; // 队列最大长度

    for(int i = 1; i <= 10; i++)
    {
        if(q.size() == maxlen)
        {
            q.pop();
        }
        q.push(i);

        cout << "队列元素:";
        while(!q.empty())
        {
            cout << q.front() << " ";
            q.pop();
        }
        cout << endl;
    }

    return 0;
}

上述代码中,我们定义了一个queue容器,然后通过循环向队列中添加元素。当队列长度达到最大长度时,就要删除队首元素以保持队列长度不变。最后,我们遍历队列输出所有元素。

vector实现

这里也是用模板泛化一下

#include <iostream>
#include <vector>

using namespace std;

template<typename T>
class FixedQueue {
private:
    vector<T> q;
    size_t size;
public:
    FixedQueue(size_t s) : size(s) {
        q.reserve(size);
    }

    void push(const T& t) {
        if (q.size() >= size) {
            q.erase(q.begin());
        }
        q.push_back(t);
    }

    T pop() {
        T t = q.front();
        q.erase(q.begin());
        return t;
    }

    T& front() {
        return q.front();
    }

    T& back() {
        return q.back();
    }

    bool empty() const {
        return q.empty();
    }

    size_t getSize() const {
        return q.size();
    }

    void clear() {
        q.clear();
    }
};

int main() {
    FixedQueue<int> fq(5);
    fq.push(1);
    fq.push(2);
    fq.push(3);
    fq.push(4);
    fq.push(5);
    fq.push(6);
    fq.push(7);
    cout << fq.front() << endl;
    cout << fq.back() << endl;
    fq.pop();
    cout << fq.front() << endl;
    cout << fq.back() << endl;
    cout << fq.empty() << endl;
    cout << fq.getSize() << endl;
    fq.clear();
    cout << fq.empty() << endl;
    cout << fq.getSize() << endl;
    return 0;
}

在这个FixedQueue类中,pop操作的时间复杂度比较高,因为它需要将队列的头部元素删除,然后将后面的元素向前移动一格,以保持元素的连续性。当队列中的元素较多时,这个操作的时间复杂度会比较高,可能会影响程序的性能。
下面给出一个优化版本:

#include <iostream>
#include <vector>

using namespace std;

template <typename T>
class CircularQueue {
private:
    vector<T> data;
    int head;
    int tail;
    int size;
    int count;
public:
    CircularQueue(int k) {
        data.resize(k);
        head = -1;
        tail = -1;
        size = k;
        count = 0;
    }

    bool enQueue(T value) {
        if (isFull()) {
            deQueue();
        }
        if (isEmpty()) {
            head = 0;
        }
        tail = (tail + 1) % size;
        data[tail] = value;
        count++;
        return true;
    }

    bool deQueue() {
        if (isEmpty()) {
            return false;
        }
        if (head == tail) {
            head = -1;
            tail = -1;
            count = 0;
            return true;
        }
        head = (head + 1) % size;
        count--;
        return true;
    }

    T Front() {
        if (isEmpty()) {
            return T();
        }
        return data[head];
    }

    T Rear() {
        if (isEmpty()) {
            return T();
        }
        return data[tail];
    }

    bool isEmpty() {
        return head == -1;
    }

    bool isFull() {
        return count == size;
    }

    void Print() {
        if (isEmpty()) {
            cout << "Queue is empty." << endl;
            return;
        }
        int i = head;
        cout << "Queue: ";
        while (i != tail) {
            cout << data[i] << " ";
            i = (i + 1) % size;
        }
        cout << data[tail] << endl;
    }

    T Get(int index) {
        if (isEmpty() || index < 0 || index >= count) {
            return T();
        }
        return data[(head + index) % size];
    }
};

测试用例

int main() {
    CircularQueue<int> q(5);
    q.enQueue(1);
    q.enQueue(2);
    q.enQueue(3);
    q.enQueue(4);
    q.enQueue(5);
    q.Print();  // should print "Queue: 1 2 3 4 5"
    q.enQueue(6);
    q.Print();  // should print "Queue: 2 3 4 5 6"
    cout << q.Rear() << endl;  // should return 6
    q.deQueue();
    q.deQueue();
    cout << q.Front() << endl;  // should return 4
    cout << q.isFull() << endl;  // should return false
    cout << q.isEmpty() << endl;  // should return false
    q.Print();  // should print "Queue: 4 5 6"
    cout << q.Get(0) << endl;  // should return 4
    cout << q.Get(1) << endl;  // should return 5
    cout << q.Get(2) << endl;  // should return 6
    cout << q.Get(3) << endl;  // should return 0
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++用vector实现定长队列 的相关文章

  • 微信小程序实现搜索功能以及效果(超详细)

    我们先来看一下实现哪些功能 1 搜索历史记录以及清空历史记录 2 热门搜索推荐以及更新推荐内容 3 根据输入框输入的内容来自动搜索相关查询 后台逻辑是模糊查询 后台就先不扯了 这里我用的是自己定义的虚拟数据 暂时没用后台接口 可能有点问题
  • 微信小程序实现收货地址城市选择效果(添加收货地址)

    先来张效果图 这里主要是城市选择效果 请忽视其他 不要吐槽 谢谢 接下来看一下代码吧 wxml lt pages my my add address index wxml gt lt view class 61 34 redact addr
  • uni-app实现商城多商家购物车功能(超详细, 附带源码)

    我们先来看一下效果 有什么不懂可以直接下方留言 先来看代码 lt template gt lt view class 61 34 cart 34 gt lt 购物车为空 S gt lt view v if 61 34 cartList le
  • 微信小程序web-view的使用教程

    最近公司有需求 xff0c 需要点击小程序首页banner xff0c 跳转到别人的h5页面 首先是域名的问题 xff1a 步骤 xff1a 先登录小程序开发平台 xff0c 将页面需要跳转的域名写上去 xff0c 注意了 xff0c 域名
  • uni-app实现上传图片裁剪效果(附源码)

    我们先来看一下效果 封装一个组件在components下创建一个 文件夹随意命名 xff0c 这里我是uni img cropper uni img cropper vue lt template gt lt view class 61 3
  • js 一维数组和二维数组实现足迹、浏览记录等场景

    再开发过程中 xff0c 再没有接口提供的情况下来实现浏览记录或者搜索记录等场景 我们可以利用本地缓存实现 xff0c 废话不多说 xff0c 直接上代码 xff1a 多维数组 64 param Array arr 数组 64 param
  • Markdown使用(超详细)

    xff08 HBuilderX xff09 掌握md及HBuilderX对md的强大支持 如果没有点右键设置自动换行 xff0c 可按Alt 43 滚轮横向滚动查看 很多人只把markdown用于网络文章发表 xff0c 这糟蹋了markd
  • 宫格导航 (自定义更灵活,超详细)

    先来看一下效果 调用方法 lt 页面调用 gt lt nav grid list 61 34 menu 34 64 click 61 34 34 gt lt nav grid gt 数据 export default data return
  • Firefox和Chromedriver驱动下载及安装步骤

    Mozilla Firefox Mozilla Firefox 中文名称 34 火狐 34 是由一个自由及开放源代码的网页浏览器 使用Gecko排版引擎 支持多种操作系统 如 Windows Mac OS X 及GNU Linux等 该浏览
  • 流媒体选择Nginx是福还是祸?

    流媒体选择Nginx是福还是祸 xff1f CDN xff0c 视频云 xff0c 已经 僧多粥少 视频直播的持续升温 xff0c 无意间也让带宽生意的争夺变得异常残酷 一时间 xff0c 各种云计算 CDN 视频云提供商都在视频尤其是直播
  • xpath去除换行\空格

    使用xpath获取文本内容 有空格或者换行就用normalize space 方法 例 intro li 61 div xpath 39 normalize space div 64 class 61 34 bookinfo 34 p te
  • Java 静态域和静态方法

    main方法都被标记为static修饰符 xff0c 本文讨论一下该修饰符含义 静态域和静态方法 一 静态域静态常量 二 静态方法三 工厂方法 一 静态域 若把域定义为static xff0c 则每个类中只有一个这样的域 而每一个对象对于所
  • Linux下传感器驱动。rk3399

    基于rk3399的Linux下的陀螺仪mpu9250传感器驱动 mpu6050 bh1750传感器 xff0c sht30 35温湿度传感器驱动 已经成功移植 xff0c 通过iic驱动获取到数据 Linux驱动开发
  • DaSaimRPN代码运行记录

    demo py xff1a 下载模型 SiamRPNVOT model 放入 code 文件夹即可 test otb py xff1a 在网上下载 OTB2015 数据集放入 data 文件夹中 更改 parser 参数 dataset 运
  • Linux环境下LLVM 6.0 + clang安装步骤

    可以转载 xff0c 请注明出处 xff01 1 准备工作 首先确保你的Linux系统是可以联网的 xff0c 我是win10环境下的VMware 15 43 centos 7 xff0c 这个应该没影响 xff0c 之所以说 xff0c
  • Pixhawk ulog飞行日志分析

    在python下安装pyulog xff0c 在 ulog文件目录下输入ulog2csv即可将ulog转化为csv形式输出 ulog文件的保存时间 43 8即为飞行实际的时间 timestamp为时间戳 xff0c 除以10 6后单位为秒
  • java看书规划

    Java编程思想 大话设计模式 重构 改善既有代码的设计 effective java 深入理解Java虚拟机 Java并发编程实战 深入理解计算机系统 xff0c tcp ip详解 卷一 二 三 xff0c 数据结构与算法 xff08 三
  • 学习ROS常用的官方网站,学习资源整理

    1 ROS仿真知识点rviz urdf gazebo的知识点网站 xff1a https wiki ros org urdf http wiki ros org rviz http gazebosim org tutorials tut 6
  • 双非末流一本大四在校生第一次线下面试总结(嵌入式软件实习生方向)

    嵌入式软件实习生面试经验总结 面试写到的技能一定要熟悉 一定要边学习边找工作 xff0c 当你技能不够的时候还是先去学习吧 面试时间 xff1a 11 11 面试公司 xff1a 北京迅为电子有限公司 笔试题目 xff1a xff08 其实
  • linux ubuntu 无法显示回收站内容

    最近一直无法查看回收站的内容 xff0c 沙漏一直转 xff0c 最后直接就显示为空 索性直接忽略 xff0c 从回收站文件中把需要的东西cp mv出来 回收站文件放在 xff1a local share Trash files 里 xff

随机推荐