Queue 队列的实现与应用

这篇具有很好参考价值的文章主要介绍了Queue 队列的实现与应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.概念

只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(FirstIn First Out) 入队列:进行插入操作的一端称为队尾(Tail/Rear) 出队列:进行删除操作的一端称为队(Head/Front),队列可以通过数组和链表两种方式来实现。
队列的基本操作:入队(Offer)、出队(Poll)和获取队头元素(Peek)。其中,入队操作将元素放到队尾,出队操作将对头元素移除并返回其值,获取队头元素则是获取栈顶元素的值但是不移除队头元素。
另外,队列还有一些其他的常用操作,如:判断队列是否为空(IsEmpty)、获取队列中元素的个数(Size)、清空队列中的所有元素(Clear)等。

Queue 队列的实现与应用

2.常用的队列方法

2.1 方法

方法 功能
offer() 入队列
poll() 出队列,队列为空,抛出NoSuchElementException异常
peek() 获得队头元素,抛出NoSuchElementException异常
size() 获得队列元素个数
isEmpty() 检测队列是否为空

2.2 代码

    public static void main(String[] args) {
        Queue<Character> queue = new LinkedList<>();
        queue.offer('A');//A
        queue.offer('B');//B A
        queue.offer('C');//C B A
        System.out.println(queue.poll());//A
        System.out.println(queue.peek());//B
        System.out.println(queue.poll());//B
        queue.offer('D');//D C
        System.out.println(queue.size());//2
        System.out.println(queue.isEmpty());//fasle
    }

注意:
队列操作的poll(),peek()的执行条件是队列不为空。

3.自己实现队列

自己实现队列可以使用线性结构和链式结构实现,具体使用哪种结构取决于实际需求和场景。
顺序结构的优点是实现简单,易于理解和维护,内存利用率高,适用于元素个数固定、连续存储空间较大时的情况。但是,在元素插入和删除时需要移动大量元素,所以当队列操作频繁时,效率可能较低。
链式结构的优点是插入和删除操作时只需修改指针,效率较高,适用于元素个数不确定、动态增长的情况。但是,链式结构需要更多的内存空间来存储指针,且代码实现相对复杂,对于较小的队列可能会浪费一些内存空间。
因此,根据具体需求和场景来选择队列的实现方式。队列可以使用顺序结构和链式结构来实现,具体使用哪种结构取决于实际需求和场景。
顺序结构的优点是实现简单,易于理解和维护,内存利用率高,适用于元素个数固定、连续存储空间较大时的情况。但是,在元素插入和删除时需要移动大量元素,所以当队列操作频繁时,效率可能较低。
链式结构的优点是插入和删除操作时只需修改指针,效率较高,适用于元素个数不确定、动态增长的情况。但是,链式结构需要更多的内存空间来存储指针,且代码实现相对复杂,对于较小的队列可能会浪费一些内存空间。
因此,根据具体需求和场景来选择队列的实现方式。

3.1 构造MyQueue

我们可以使用链表构建队列,链表是节点组成,所以我们创建节点,用next记录下一个节点,prev记录前一个节点。

public class MyQueue {
    public int val;
    public MyQueue next;
    public MyQueue prev;
    public MyQueue first;//队头
    public MyQueue last;//队尾
    public int size;//元素个数
    public MyQueue(){}
    public MyQueue(int val){
        this.val = val;
    }
}    

3.2 入队列offer()

入队列的时候,如果队列大小为0,则队头队尾都等于这个节点。不为0,则直接队尾插入这个节点。

    //入队列
    public void offer(int val){
        MyQueue myQueue = new MyQueue(val);
        if(size == 0){
            first = myQueue;
            last = myQueue;
            size++;
            return;
        }
        last.next = myQueue;
        myQueue.prev = last;
        last = last.next;
        size++;
    }

3.3 出队列poll()

出队列的时候,判断队列大小是否为0,为零则抛出异常,不为0则删除队头元素,并返回。

    //出队列
    public int poll(){
        if(first == null){
            throw new NoSuchElementException();
        }
        MyQueue myQueue = first;
        if(first == last){
            last = null;
            first = null;
        }else {
            first = first.next;
            first.prev = null;
        }
        size--;
        return myQueue.val;
    }

3.4 获得队头peek()

获得队头元素,若队列为空,直接抛出异常,反之直接返回队头元素。

    //获得队头元素
    public int peek(){
        if(first == null){
            throw new NoSuchElementException();
        }
        return first.val;
    }

3.5 是否为空isEmpty()

判断队列是否为空,就是判断size是否为0。

    //是否为空队列
    public boolean isEmpty(){
        return size == 0;
    }

3.6 获得队列大小size()

获得队列大小,直接返回size即可。

    //队列元素个数
    public int getSize(){
        return size;
    }

4.循环队列

4.1 概念

用数组来实现,是一种队列数据结构,它通过维护两个指针front和rear,使得在队列头和队列尾之间形成一个环状的结构。当队列满时,新元素无法插入队列,但是可以从队头删除元素来腾出空间。与普通队列相比,循环队列可以更有效地利用存储空间。另外,循环队列还有一些特殊操作,如队列的遍历和求队列长度,它们需要特殊的算法来实现。文章来源地址https://www.toymoban.com/news/detail-469142.html

4.2 解析

  1. MyCircularQueue类有三个私有成员变量:elem表示循环队列的存储数组,front、rear分别表示队头和队尾的位置。
  2. 构造函数MyCircularQueue(int capacity)用于创建一个容量为k的循环队列。在构造函数中,初始化存储数组elem、队头front、队尾rear。
  3. enQueue方法用于向队列中添加元素element。如果队列已满,则返回false;否则将元素添加到队尾,并将队尾指针rear移动到下一个位置,同时更新队列大小size。注意,队列满时,rear可能会回到数组的开始位置,这时可以用取模运算实现。rear = (rear + 1) % elem.length;
  4. deQueue()方法用于从队列中删除元素,并返回被删除的元素。如果队列为空,则抛出NoSuchElementException。否则将队头元素删除,并将队头指针front移动到下一个位置。同样地,如果队头指针front回到数组的开始位置,则也需要用取模运算实现。frond = (frond + 1) % elem.length;
    peek()方法用于返回队头元素,但不删除它。如果队列为空,则抛出NoSuchElementException。
    Queue 队列的实现与应用

4.3 如何判断队列满

  1. 通过添加 size 属性记录(当size等于队列长度,满)
  2. 保留一个位置(当队尾加1 mod 队列长度等于队头,队列满)
  3. 使用标记(在循环队列中添加一个标记 flag,用来区分队列空和队列满的状态。)

4.4 代码(保留一个位置实现)

class MyCircularQueue {
    private int[] elem;
    private int rear;
    private int frond;
    public MyCircularQueue(int k) {
        this.elem = new int[k];
    }
    
    public boolean enQueue(int value) {
        if(isFull()){
            return false;
        }
        elem[rear] = value;
        rear = (rear + 1) % elem.length;
        return true;
    }
    
    public boolean deQueue() {
        if(isEmpty()){
            return false;
        }
        frond = (frond + 1) % elem.length;
        return true;
    }
    
    public int Front() {
        if(isEmpty()){
            return -1;
        }
        return elem[frond];
    }
    
    public int Rear() {
        if(isEmpty()){
            return -1;
        }
        return elem[rear];
    }
    
    public boolean isEmpty() {
        return frond == rear;
    }
    
    public boolean isFull() {
        return (rear + 1) % elem.length == frond;
    }
}

到了这里,关于Queue 队列的实现与应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】队列(Queue)的实现 -- 详解

    1、概念 队列 :只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有 先进先出 FIFO(First In First Out)。 入队列 :进行 插入 操作的一端称为 队尾 。 出队列 :进行 删除 操作的一端称为 队头 。 2、结构 (1)队列的顺序存储结构 入队 ,不需要

    2024年02月15日
    浏览(28)
  • golang实现延迟队列(delay queue)

    延迟队列:处理需要在未来某个特定时间执行的任务。这些任务被添加到队列中,并且指定了一个执行时间,只有达到指定的时间点时才能从队列中取出并执行。 应用场景: 邮件提醒 订单自动取消(超过多少时间未支付,就取消订单) 对超时任务的处理等 由于任务的执行

    2024年02月22日
    浏览(28)
  • 【Golang】实现简单队列(Queue)数据结构

     在计算机科学中,队列是一种特殊的线性数据结构,它遵循FIFO(先进先出)原则。队列中的元素只能从一端(称为队尾或后端)添加,并且只能从另一端(称为队头或前端)移除。这种特性使得队列在许多算法和数据结构中都有广泛的应用,例如操作系统中的任务调度、网

    2024年01月19日
    浏览(30)
  • 优先级队列priority_queue模拟实现

    🌟🌟hello,各位读者大大们你们好呀🌟🌟 🚀🚀系列专栏:【C++的学习】 📝📝本篇内容:C++容器优先级队列priority_queue模拟实现 ⬆⬆⬆⬆上一篇:string模拟实现 💖💖作者简介:轩情吖,请多多指教( •̀֊•́ ) ̖́- ①优先级队列是一种容器适配器,它的第一个元素总是

    2024年02月02日
    浏览(26)
  • Yii2-Queue实现轻量级消息队列

    Yii2-Queue是Yii2官方制作的一个消息队列,提供多个缺点:Syncronous, File, DB, Redis, RabbitMQ, AMQP Interop, Beanstalk, Gearman等,使用Yii2开发的时候使用该扩展比较合适. Syncronous 如果打开  handle  属性,则在使用过程中同步执行任务,开发和调试阶段使用. File 以文件的方式来存储消息队列 DB 使用

    2024年02月06日
    浏览(29)
  • 【C++初阶】模拟实现优先级队列priority_queue

    👦个人主页:@Weraphael ✍🏻作者简介:目前学习C++和算法 ✈️专栏:C++航路 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨ 优先级队列顾名思义就是 按优先级出队列 priority_queue 是一个容器适配器,默认使用

    2024年02月10日
    浏览(29)
  • 【C++】栈和队列(stack and queue)语法使用及实现原理

         本篇文章会对C++中的容器stack和queue用法进行详解,也包含对优先队列(priority_queue)的讲解。同时会模拟实现stack、queue和priority_queue底层。希望本篇文章会对你有所帮助! 目录 一、stack 栈 1、1 什么是适配器 1、2 stack 语法讲解 1、3 stack 底层实现 1、4 deque 双端队列简单

    2024年02月15日
    浏览(27)
  • C++——优先级队列(priority_queue)的使用及实现

    目录 一.priority_queue的使用 1.1、基本介绍 1.2、优先级队列的定义 1.3、基本操作(常见接口的使用) 1.4、重写仿函数支持自定义数据类型 二.priority_queue的模拟实现 2.1、构造重要的调整算法 2.2、常见接口的实现 push() pop() top() empty()、size()  三.利用仿函数改进调整算法 我们之前

    2024年02月02日
    浏览(29)
  • 速学数据结构 | 我不允许还有人不会用栈实现队列!

    🎬 鸽芷咕 :个人主页  🔥个人专栏 :《Linux深造日志》《C++干货基地》 ⛺️生活的理想,就是为了理想的生活!    🌈 hello! 各位铁铁们大家好啊,不知道大家对栈和队列的学习都学过了吧?那么用栈来实现队列你会做嘛?    ⛳️ 栈和队列我们前面说了都是一种特殊

    2024年02月02日
    浏览(30)
  • C++ 栈和队列(stack and queue)语法使用及底层实现原理

         本篇文章会对C++中的容器stack和queue用法进行详解,也包含对优先队列(priority_queue)的讲解。同时会模拟实现stack、queue和priority_queue底层。希望本篇文章会对你有所帮助! 目录 一、stack 栈 1、1 什么是适配器 1、2 stack 语法讲解 1、3 stack 底层实现 1、4 deque 双端队列简单

    2024年02月13日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包