数据结构-Queue队列

 一,队列的简单认识

队列也是一种线性数据结构,与栈不同的是,它只能从一端添加元素,从另一端取出元素.定义了一端,另一端也就确定了.

(当然还有一个特殊的双向队列LinkedList除外,它既可以从队首添加元素,也可以移除元素,队尾也是一样的,既可以添加元素,也可以移除元素)

二,队列的实现

Queue<E>

1,void enqueue(E) //添加元素

2,E dequeue()  //移除元素

3,E getFront() //获取第一个元素,但不移除

4,int  getSize() //获取索引

5,boolean isEmpty() //判断队列是否为空

三,队列代码实现,

了解队列的基本功能,对队列的功能进行代码实现,底层逻辑为数组,同样栈也可以实现队列的功能,队列也可以实现栈的功能.

(注意:利用泛型可以对任意类型的数据进行操作)

1,用抽象类来封装相关功能

public interface Queue<T> {
    // 入队的方法
    void enqueue(T ele);

    // 出队的方法
    T dequeue();

    // 查看队首元素
    T getFront();

    // 队列中元素的数量
    int getSize();

    // 判断队列是否为空
    boolean isEmpty();
}

2,用数组来实现队列功能

import java.util.Optional;
import java.util.Random;

// 封装属于自己的数组,使用泛型
public class CycleArray<T> {
    private T[] data; // 底层数据结构
    private int size;// 用来保存实际存放元素的个数

    private int capacity; // 表示容积

    // 声明索引
    private int front, tail;

    public CycleArray() {
        this(5);
    }

    public CycleArray(int capacity) {
        this.capacity = capacity;
        this.data = (T[]) new Object[this.capacity + 1];
        this.size = 0;
        this.front = this.tail = 0;
    }

    // 获取容积的方法
    public T getFront() {
        if (this.isEmpty()) {
            return null;
        }
        return this.data[this.front];
    }

    // 判断数组是否为空
    public boolean isEmpty() {
        return this.front == this.tail;
    }

    // 获取数组实际存放元素的个数
    public int getSize() {
        return this.size;
    }

    /**
     * 在尾部添加
     *
     * @param val 插入的值
     */
    public void addTail(T val) {

        // 在增加之前,判断数组是否已满,如果已满,要进行扩容
        if ((this.tail + 1) % this.data.length == this.front % this.data.length) {
            // 扩容操作
            resize(this.capacity * 2);
        }

        this.data[this.tail] = val;
        // 更新tail
        this.tail = (this.tail + 1) % this.data.length;
        System.out.println("入队:this.front=" + this.front + ",this.tail=" + this.tail);
        this.size += 1;
    }

    // 改变容积的方法
    private void resize(int newCapacity) {
        System.out.println("--------resize--------");
        // 2、 创建一个新数组
        T[] newArr = (T[]) new Object[newCapacity + 1];

        // 3、将原来数组的内容转移到新数组
        for (int i = 1; i <= this.size; i++) {
            newArr[i - 1] = this.data[this.front];
            this.front = (this.front + 1) % this.data.length;
        }

        this.front = 0;
        this.tail = this.size;
        System.out.println("扩容完成:this.front=" + this.front + ",this.tail=" + this.tail);
        // 4、将newArr赋值给 this.data
        this.data = newArr;
        // 5、将newCapacity 赋值给this.capacity
        this.capacity = newCapacity;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        int curIndex = this.front;
        while (curIndex != this.tail) {
            sb.append(this.data[curIndex]);
            curIndex = (curIndex + 1) % this.data.length;
        }
        String result = sb.toString();
        return result.substring(0, result.length() - 1);
    }


    // 删除队首元素
    public Optional<T> removeFromHead() {
        // 判断是否为空
        if (this.front == this.tail) {
            Optional.empty();
        }
        Optional<T> result = Optional.of(this.data[this.front]);
        // 更新front
        this.front = (this.front + 1) % this.data.length;
        this.size--;

        System.out.println("出队:this.front=" + this.front + ",this.tail=" + this.tail);

        if (this.size <= this.capacity / 4 && this.capacity / 2 > 1) {
            resize(this.capacity / 2);
        }
        return result;
    }
}

3,对功能进行封装

public class CycleQueue<T> implements Queue<T> {

    private CycleArray<T> data;

    public CycleQueue() {
        this.data = new CycleArray<>();
    }

    @Override
    public void enqueue(T ele) {
        this.data.addTail(ele);
    }

    @Override
    public T dequeue() {
        return this.data.removeFromHead().orElse(null);
    }

    @Override
    public T getFront() {
        return this.data.getFront();
    }

    @Override
    public int getSize() {
        return this.data.getSize();
    }

    @Override
    public boolean isEmpty() {
        return this.data.isEmpty();
    }
}

五,队列的复杂度分析

六,队列的优势,及用处

在Java中,队列相比栈和数组的优势:

  1. 先入先出(FIFO)的特性:队列保持元素的顺序,确保先入队的元素先被移出队列,这种特性在很多场景下非常有用;

  2. 动态增长:Java中的队列实现类(如LinkedList等)可以动态增长,不需要事先指定队列的大小,因此更灵活;

  3. 提供了更多的操作:队列通常提供了丰富的操作,如入队、出队、查看队首元素等方法,更符合队列数据结构的特性。

队列可以用于解决诸如排队、调度等问题,包括但不限于:

  1. 任务调度:可以使用队列来实现任务的排队执行,确保按照顺序进行;

  2. 缓冲区:可以用队列来作为缓冲区,平衡生产者和消费者之间的速度差异;

  3. 线程安全:多线程环境下可以利用队列来进行线程安全的数据交换;

  4. BFS算法:在图论中,广度优先搜索算法(BFS)通常使用队列来实现,以便按照层级顺序遍历节点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/409817.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

有哪些副业渠道?

夸克网盘这个软件出来好久了&#xff0c;官方前不久才开通了推广渠道&#xff0c;这就给了我们以此赚钱的机会。具体时间应该是在2022年12月份。 所谓夸克网盘拉新&#xff0c;就是夸克网盘为了抢占市场&#xff0c;与其他网盘竞争对手&#xff08;百度网盘、迅雷网盘等&#…

一键生成请求方法的工具 —— OpenAPI Typescript Codegen

文章目录 用法自定义请求参数的方法1&#xff09;使用代码生成器提供的全局参数修改对象2&#xff09;直接定义 axios 请求库的全局参数&#xff0c;比如&#xff1a;全局请求响应拦截器 报错解决 用法 首先下载axios npm install axios官网&#xff1a;https://github.com/f…

Centos中安装Docker及Docker的使用

在centos7系统中安装指定版本的docker,并通过docker使用安装mysql为例,阐述docker的使用。 2.1、Docker卸载及安装yum依赖 【卸载Docker,如果安装的Docker的版本不合适】 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-…

Kafka之Producer源码

Producer源码解读 在 Kafka 中, 我们把产生消息的一方称为 Producer 即 生产者, 它是 Kafka 的核心组件之一, 也是消息的来源所在。它的主要功能是将客户端的请求打包封装发送到 kafka 集群的某个 Topic 的某个分区上。那么这些生产者产生的消息是怎么传到 Kafka 服务端的呢&a…

常用路径规划算法简介及python程序

目录 1、前言2、D*算法2.1简介2.2优缺点2.2.1 优点2.2.2 缺点 2.3 python程序 3、A*算法3.1 优缺点&#xff1a;3.1.1 优点&#xff1a;3.1.2 缺点&#xff1a; 3.2 python程序 4、人工势场算法4.1优缺点4.1.1优点&#xff1a;4.1.2缺点&#xff1a; 4.2 python程序 5、Dijkstr…

BeautifulSoup+xpath+re+css简单复习+新的scrapy的学习

1.BeautifulSoupsoup BeautifulSoup(html,html.parser)all_icosoup.find(class_"DivTable") 2.xpath trs resp.xpath("//tbody[idcpdata]/tr") hong tr.xpath("./td[classchartball01 or classchartball20]/text()").extract() 这个意思是找…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 2月26日,星期一

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年2月26日 星期一 农历正月十七 1、 气象台&#xff1a;3月初之前南方大部将维持阴雨雪天气。 2、 据海关统计&#xff0c;京津冀协同发展十年成效显著&#xff0c;外贸总量跨两个万亿台阶。 3、 2024年研考初试成绩今天起…

【数据库】MySQL视图 | 用户管理

文章目录 1 :peach:视图:peach:1.1 :apple:基本使用:apple:1.1.1 :lemon:创建视图:lemon:1.1.2 :lemon:案例:lemon:1.1.3 :lemon:删除视图:lemon: 1.2 :apple:视图规则和限制:apple: 2 :peach:用户管理:peach:2.1 :apple:用户信息:apple:2.2 :apple:创建用户:apple:2.3 :apple:…

国企行政题库--校园招聘

国企行政题库是为准备参加国有企业行政类岗位校园招聘的应聘者提供的一套专门准备的试题资料。国有企业在中国经济中扮演着重要的角色&#xff0c;其行政类岗位需求量大&#xff0c;竞争激烈。通过系统学习和准备国企行政题库&#xff0c;将有助于应聘者更好地了解国企行政类岗…

解析OOM的三大场景,原因及实战解决方案

目录 一、什么是OOM 二、堆内存溢出&#xff08;Heap OOM&#xff09; 三、方法区内存溢出&#xff08;Metaspace OOM&#xff09; 四、栈内存溢出&#xff08;Stack OOM&#xff09; 一、什么是OOM OOM 是 Out Of Memory 的缩写&#xff0c;意思是内存耗尽。在计算机领域…

Centos服务器部署前后端项目

目录 准备工作1. 准备传输软件2. 连接服务器 部署Mysql1.下载Mysql(Linux版本)2. 解压3. 修改配置4. 启动服务另一种方法Docker 部署后端1. 在项目根目录中创建Dockerfile文件写入2. 启动 部署前端1. 在项目根目录中创建Dockerfile文件写入2. 启动 准备工作 1. 准备传输软件 …

QEMU源码全解析 —— virtio(24)

接前一篇文章&#xff1a; 上回书讲解了virtioballoon_probe函数及其中的两个重要函数init_vqs()和virtio_device_ready()&#xff0c;解析了init_vqs函数的前两步&#xff0c;本回继续解析该函数&#xff0c; &#xff08;3&#xff09;init_vqs函数在经过了对于各feature的初…

【电机仿真】HFI算法脉振高频电压信号注入观测器-PMSM无感FOC控制

【电机仿真】HFI算法脉振高频电压信号注入观测器-PMSM无感FOC控制 文章目录 前言一、脉振高频电压注入法简介&#xff08;注入在旋转坐标系的d轴&#xff09;1.旋转高频电压&#xff08;电流&#xff09;注入法2.脉振高频电压注入法 二、高频注入理论1.永磁同步电机的高频模型2…

EasyRecovery2024个人免费版本电脑手机数据恢复软件下载

EasyRecovery是一款功能强大的数据恢复软件&#xff0c;能够帮助用户恢复丢失、删除、格式化或损坏的数据。无论是由于误操作、病毒攻击、硬盘故障还是其他原因导致的数据丢失&#xff0c;EasyRecovery都能提供有效的解决方案。 该软件支持从各种存储介质恢复数据&#xff0c;…

springboot215基于springboot技术的美食烹饪互动平台的设计与实现

美食烹饪互动平台的设计与实现 摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统美食信息管理难度大&…

密码安全+破解+防御

一步一脚印&#xff01; 目录 密码安全简介 密码猜解思路 字典生成 crunch工具(kali自带) 社工生成字典(safe6pwd)&#xff1a; python代码实现暴力破解 burpsuite爆破 验证码自动识别 hydra爆破ssh密码 hydra工具 medusa爆破ssh密码 medusa工具 msf爆破ssh密码 …

基于YOLOv8深度学习+Pyqt5的电动车头盔佩戴检测系统

wx供重浩&#xff1a;创享日记 对话框发送&#xff1a;225头盔 获取完整源码源文件已标注的数据集&#xff08;1463张&#xff09;源码各文件说明配置跑通说明文档 若需要一对一远程操作在你电脑跑通&#xff0c;有偿89yuan 效果展示 基于YOLOv8深度学习PyQT5的电动车头盔佩戴检…

Open3D 基于最小生成树的法线定向 (27)

Open3D 基于最小生成树的法线定向 (27) 一、算法介绍二、算法实现一、算法介绍 法线计算的方向通常都存在方向问题,用Open3D估计的点云法线,是在每个点的局部进行拟合,估计的法线方向并不一致,Open3D提供了使用最小生成树调整法线到统一方向的方法,下面是具体的实现代码…

微服务-微服务Spring Security OAuth 2实战

1. Spring Authorization Server 是什么 Spring Authorization Server 是一个框架&#xff0c;它提供了 OAuth 2.1 和 OpenID Connect 1.0 规范以及其他相关规范的实现。它建立在 Spring Security 之上&#xff0c;为构建 OpenID Connect 1.0 身份提供者和 OAuth2 授权服务器产…

【机器人学导论笔记】三、操作臂正运动学

3.1 概述 操作臂正运动学研究操作臂的运动特性&#xff0c;主要涉及与运动有关的几何参数和时间参数。本章中&#xff0c;只研究静止状态下操作臂连杆的位置和姿态。 处理这些复杂的几何参数需要一些步骤&#xff1a;首先需要在操作臂的每个连杆上分别固接一个连杆坐标系&…