首页 > 其他分享 >第4章. 队列(Queue)

第4章. 队列(Queue)

时间:2023-12-06 20:35:26浏览次数:28  
标签:return 队列 void list Queue public size

队列(Queue)


一、队列的基本概念

  • 队列是一种特殊的线性表,只能在头尾两端进行操作
  • 队尾(rear):只能从队尾添加元素,一般叫做enQueue,入队
  • 队头(front):只能从队头移除元素,一般叫做deQueue,出队
  • 先进先出的原则,FIRST IN FIRST OUT,FIFO

二、队列的接口设计

  • int size(); // 元素的数量
  • boolean isEmpty(); // 队列是否为空
  • void clear(); // 清空
  • void enQueue(E element); // 入队
  • E deQueue(); // 出队
  • E front(); // 获取队列的头元素
  • 队列的内部实现可以直接用以前学过的数据结构:动态数组,链表
  • 优先使用双向链表,因为队列主要是往头尾操作元素
方法一:继承之前写的ArrayList或DoubleLinkedList

用动态数组效率低,推荐使用双向链表。

package DataStructure._05队列;

import DataStructure._01动态数组.ArrayList;

/**
 * @author keyongkang
 * @date 2022-07-22-20:03
 */
public class Queue<E> extends ArrayList<E> {

    // 元素的数量
    public int size() {
        return super.size();
    }

    // 判断队列是否为空
    public boolean isEmpty() {
        return super.isEmpty();
    }

    // 清空
    public void clear() {
        super.clear();
    }

    // 入队
    public void enQueue(E element) {
        add(0, element);
    }

    // 出队
    public E deQueue() {
        return remove(size() - 1);
    }

    // 获取队列的头元素
    public E front() {
        return get(size() - 1);
    }
}
方法二:把Java内置的LinkedList作为Stack的成员变量
package DataStructure._05队列;

import java.util.LinkedList;
import java.util.List;

/**
 * @author keyongkang
 * @date 2022-07-22-20:03
 */
public class Queue<E>  {
    private List<E> list = new LinkedList<>(); // 索引0的位置记作队头,最后的位置记作队尾

    // 元素的数量
    public int size() {
        return list.size();
    }

    // 判断队列是否为空
    public boolean isEmpty() {
        return list.isEmpty();
    }

    // 清空
    public void clear() {
        list.clear();
    }

    // 入队
    public void enQueue(E element) {
        list.add(element);
    }

    // 出队
    public E deQueue() {
        return list.remove(0);
    }

    // 获取队列的头元素
    public E front() {
        return list.get(0);
    }
}

三、Java官方Queue实现

Java中LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue使用

  • Queue< String > queue = new LinkedList<>();

常用的操作:

  • peek():返回队头
  • size():返回队长
  • poll():获取并移除此队头,如果为空,则返回null
  • remove():获取并移除此队列的头
  • offer(E e):队尾添加。添加成功返回true,添加失败返回false
  • add(E e):队尾添加。如果容量允许将会返回true,否则抛异常

双端队列(Deque—double ended queue)

  • 双端队列是能再头尾两端添加、删除的队列(队头、队尾都可以入队和出队)
  • 英文deque是Double ended queue的简称

四、双端队列的接口设计

  • int size():元素的数量
  • boolean isEmpty():是否为空
  • void enQueueRear(E element):从队尾入队
  • void enQueueFront(E element):从队头入队
  • E deQueueFront():从队头出队
  • E deQueueRear(): 从队尾出队
  • E front():获取队列的头元素
  • E rear():获取队列的尾元素
  • void clear():清空队列的所有元素

由于双端队列需要在头尾进行插入和删除操作,所以我们使用双向链表来实现

方法一:继承之前写的DoubleLinkedList(省略)
方法二:把Java内置的LinkedList作为Deque的成员变量
package DataStructure._05队列;

import java.util.LinkedList;
import java.util.List;

/**
 * @author keyongkang
 * @date 2022-07-23-9:45
 */
public class Deque<E> {
    private List<E> list = new LinkedList<>();

    // 元素的数量
    public int size() {
        return list.size();
    }

    // 是否为空
    public boolean isEmpty() {
        return list.isEmpty();
    }

    // 清空
    public void clear() {
        list.clear();
    }

    // 从队尾入队
    public void enQueueRear(E element) {
        list.add(element);
        //list.add(list.size(), element);
    }

    // 从队头入队
    public void enQueueFront(E element) {
        list.add(0, element);
    }

    // 从队头出队
    public E deQueueFront() {
        return list.remove(0);
    }

    // 从队尾出队
    public E deQueueRear() {
        return list.remove(list.size() - 1);
    }

    // 获取队列的头元素
    public E front() {
        return list.get(0);
    }

    // 获取队列的尾元素
    public E rear() {
        return list.get(list.size() - 1);
    }
}

五、Java官方Deque实现

Java官方用LinkedList实现了Deque接口

  • Deque< Integer > deque = new LinkedList<>();

循环队列(Circle Queue)

  • 循环队列底层使用数组来实现

其实队列的底层也可以使用动态数组实现,并且各项接口也可以优化到O(1)的时间复杂度,这个用数组实现并且优化之后的队列叫做:循环队列

入队/出队:

扩容:

从对头开始,依次把所有元素放在新数组中,然后将front置位0。

循环双端队列(Circle Deque)

循环双端队列:可以进行两端添加、删除操作的循环队列。

标签:return,队列,void,list,Queue,public,size
From: https://www.cnblogs.com/keyongkang/p/17880454.html

相关文章

  • Rabbitmq队列
    rabbitmq消息中间件-消息队列异步开发语言erlang爱立信公司1.安装pythonrabbitMQmodule 1pip3installpika关闭防火墙1serviceiptablesstop关闭防火墙2.实现最简单的队列通信send端:1#send端2importpika34credentials=pika.PlainCredent......
  • 消息队列
    简介:在C#中,消息队列是一种用于在应用程序之间异步传递消息的通信机制。它通常被用于异步通信,允许发送者和接收者在不需要立即相互作用的情况下进行消息交换,可以用来解耦应用程序的各个组件,实现分布式系统之间的通信,并提供可靠性和可扩展性。消息队列系统通常包括以下核心组件:......
  • 单调栈与单调队列算法总结
    单调栈知识概览单调栈最常见的应用是找到每一个数离它最近的且比它小的数。单调栈考虑的方式和双指针类似,都是先想一下暴力做法是什么,然后再挖掘一些性质如单调性,最终可以把目光集中在比较少的状态中,从而达到降低时间复杂度的作用,都是算法优化的一种手段。对于的情况,更有可能......
  • [GraphicBufferSource](id:5cd400000003,api:1,p:1674,c:23764) cancelBuffer: Buffer
    开发中遇到的问题,这个问题吧属于我们公司开发使用的RSR然后我们做好的app就是一个录屏软件将视频推到RSR当中去,可是推送的同时只会在RSR中出现一下我查看日志文件输出的信息唯一出现爆红的地方就是GraphicBufferSourcecancelBuffer:BufferQueuehasbeenabandoned这个,有没有经......
  • 八、延迟队列
    一、延迟队列的概念二、延迟队列使用场景三、RabbitMQ中的TTL1、消息设置TTL2、队列设置TTL3、两者的区别四、整合springboot1、创建项目2、添加依赖3、修改配置文件4、添加Swagger配置类五、队列TTL1、代码架构图2、配置文件类代码3、消息生......
  • PriorityBlockingQueue 优先级队列
    packagestudy;importlombok.Data;importjava.util.Comparator;importjava.util.concurrent.PriorityBlockingQueue;publicclassPriorityBlockingQueueDemo{publicstaticvoidmain(String[]args)throwsInterruptedException{PriorityBlocki......
  • Workqueue (翻译 by chatgpt)
    原文:https://www.kernel.org/doc/html/latest/core-api/workqueue.htmlIntroductionTherearemanycaseswhereanasynchronousprocessexecutioncontextisneededandtheworkqueue(wq)APIisthemostcommonlyusedmechanismforsuchcases.有许多情况需要异步处......
  • 98、swift--- tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPat
    作用:复用cell.可以用标识符从表视图中获得可重用单元格.for:indexPath通过指定单元格位置获得可重用单元格,不需要判断.用于dequeue(出队)一个可复用的cell,用于在UITableView或UICollectionView中显示。这个方法接收两个参数:withIdentifier:一个字符串,表示要dequeue的......
  • 为什么stack和queue默认使用deque作为底层容器?
    在C++中,stack和queue默认使用deque作为底层容器的原因主要有以下几点:操作效率:deque(双端队列)支持在头尾两端进行插入和删除操作,且时间复杂度都为O(1),非常高效1。而vector在增长到一定长度时为了保证完全连续,需要重新申请更长的内存,并把原来的元素全部拷贝过去2。这使得vector......
  • stack和queue的底层容器封装 以及提供随机存储的容器
    在C++中,std::stack和std::queue是容器适配器,它们提供了特定的接口,依赖于某个容器类(如std::deque或std::list)来处理元素1。std::stack:std::stack默认使用std::deque作为其底层容器2。但是,你也可以在创建std::stack对象时指定其他的底层容器,只要这个容器支持......