数据结构-Queue队列

news2024/11/15 12:15:16

 一,队列的简单认识

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

(当然还有一个特殊的双向队列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)通常使用队列来实现,以便按照层级顺序遍历节点。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI误导游戏——LLM的危险幻觉

在当今科技高速发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;已成为日常生活和工作中不可或缺的一部分。特别是大语言模型&#xff08;LLM&#xff09;如GPT-4等&#xff0c;它们的智能表现令人惊叹&#xff0c;广泛应用于文本生成、语言翻译、情感分析等多个领域…

【rust】9、reqwest 调用 http

文章目录 一、client1.1 post reqwest 实现的 http server 和 client 用 https://github.com/seanmonstar/reqwest cargo add reqwest -F json cargo add tokio -F full一、client 1.1 post async fn http_post<T: Serialize>(addr: String, body: T) -> Result<…

jQuery 基础、选择器和筛选器

【一】JQuery基础 【1】什么时Jquery &#xff08;1&#xff09;定义 jQuery是一个流行的JavaScript库&#xff0c;旨在简化JavaScript编程和处理HTML文档的任务。它提供了一组易于使用的功能和方法&#xff0c;可以加快开发速度并提高跨浏览器兼容性。一款轻量级的JS框架 …

【Java程序设计】【C00285】基于Springboot的游戏分享网站(有论文)

基于Springboot的游戏分享网站&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的游戏分享网站 本系统分为系统功能模块、管理员功能模块以及用户功能模块。 系统功能模块&#xff1a;在网站首页可以查看首页、游戏…

element 季度选择器组件

效果图&#xff1a; 回传给父组件的值&#xff1a; 季度选择器组件代码&#xff1a; <template><el-form><el-form-item><markclass"mark"v-show"showSeason"click.stop"showSeason false"></mark><el-input…

web安全学习笔记【15】——信息打点(5)

信息打点-CDN绕过&业务部署&漏洞回链&接口探针&全网扫描&反向邮件 #知识点&#xff1a; 1、业务资产-应用类型分类 2、Web单域名获取-接口查询 3、Web子域名获取-解析枚举 4、Web架构资产-平台指纹识别 ------------------------------------ 1、开源-CMS指…

大数据之Flink优化

文章目录 导言&#xff1a;Flink调优概览第1章 资源配置调优1.1 内存设置1.1.1 TaskManager 内存模型1.1.2 生产资源配置示例 1.2 合理利用 cpu 资源1.2.1 使用 DefaultResourceCalculator 策略1.2.2 使用 DominantResourceCalculator 策略1.2.3 使用DominantResourceCalculato…

RM电控讲义【HAL库篇】(二)

8080并口模式是一种常见的计算机接口模式&#xff0c;主要用于LCD&#xff08;液晶显示屏&#xff09;模块。 在8080并口模式中&#xff0c;通信端口包括多种信号线&#xff0c;用于实现数据的读写和控制功能。主要的信号线包括&#xff1a; CS&#xff08;片选信号&#xff…

测绘测量行业CRM功能大揭秘:哪家才是最佳选择?

测绘测量行业面临着处理及管理海量数据的难题。办公软件进行数据记录是非常繁琐的&#xff0c;往往需要花费大量的时间来查找所需的信息&#xff0c;甚至造成内容丢失。测绘测量企业运用CRM管理系统至关重要。本文将向您介绍测绘测量行业CRM功能、哪家好&#xff1f; CRM软件的…

在线程调用的函数中使用pthread_exit同样会将线程退出

如上图所示&#xff0c;在func()函数中调用pthread_exit&#xff0c;同样可以退出当前线程&#xff1b; 类似的&#xff0c;如果func&#xff08;&#xff09;函数中调用exit&#xff0c;可以直接退出整个进程。 return 是返回到函数调用处&#xff1b; pthread_exit是退出…

数字化转型导师坚鹏:如何制定政府数字化转型年度培训规划

如何制定政府数字化转型年度培训规划 ——以推动政府数字化转型战略落地为核心&#xff0c;实现知行果合一 课程背景&#xff1a; 很多政府都在开展政府数字化转型培训工作&#xff0c;目前存在以下问题急需解决&#xff1a; 缺少针对性的政府数字化转型年度培训规划 不清…

127 Linux 系统编程5 ,C++程序内存布局图

我们以32位 系统说明。 0-3G 是用户区 3g-4g 是kernel 区 BSS段&#xff1a;BSS段&#xff08;bss segment&#xff09;通常是指用来存放程序中未初始化的或者初始值为0的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。 数据段…

C语言中的assert.h:调试助手与断言详解

在C语言编程中&#xff0c;assert.h头文件提供了非常有用的断言&#xff08;Assertion&#xff09;功能&#xff0c;它主要用于开发和调试阶段&#xff0c;确保程序在运行时满足某些预期条件。如果这些条件未得到满足&#xff0c;则程序会立即停止执行&#xff0c;并打印出有关…

C++之std::async

std::async是C提供的一个异步处理函数。 函数原型&#xff1a; template<typename _Fn, typename... _Args> future<__async_result_of<_Fn, _Args...>> async(launch __policy, _Fn&& __fn, _Args&&... __args); 参数说明: int thFun(in…

[rust] 11 所有权

文章目录 一 背景二 Stack 和 Heap2.1 Stack2.2 Heap2.3 性能区别2.4 所有权和堆栈 三 所有权原则3.1 变量作用域3.2 String 类型示例 四 变量绑定背后的数据交互4.1 所有权转移4.1.1 基本类型: 拷贝, 不转移所有权4.1.2 分配在 Heap 的类型: 转移所有权 4.2 Clone(深拷贝)4.3 …

京东前端笔试(附答案解答)

引言 我目前本科大四&#xff0c;正在春招找前端&#xff0c;有大厂内推的友友可以聊一聊&#xff0c;球球给孩子的机会吧。 我整理了一份10w字的前端技术文档&#xff1a;https://qx8wba2yxsl.feishu.cn/docx/Vb5Zdq7CGoPAsZxMLztc53E1n0k?fromfrom_copylink &#xff0c;对…

Java基础知识点:入门篇(一)

目录 Java起源第一个Java程序注意点 Java基本语法Java标识符命名规范&#xff08;驼峰命名法&#xff09;注意点 Java修饰符访问控制修饰符privateprotectedpublicdefault 非访问控制修饰符final修饰符abstract修饰符synchronized 修饰符transient 修饰符volatile 修饰符 Java变…

adb-环境安装

1. 下载解压包&#xff1a;百度网盘 请输入提取码百度网盘为您提供文件的网络备份、同步和分享服务。空间大、速度快、安全稳固&#xff0c;支持教育网加速&#xff0c;支持手机端。注册使用百度网盘即可享受免费存储空间https://pan.baidu.com/s/1TDu2fzGbqCyug3wCSmV9oQ?pwd…

Git基本操作(1)

Git基本操作&#xff08;1&#xff09; 初始化git本地仓库git本地仓库配置git config user.name 和git config user.emailgit config --unset user.name和git config --unset user.emailgit config --global 认识工作区&#xff0c;暂存区&#xff0c;版本库更深层次理解 git a…

Spring基础之AOP和代理模式

文章目录 理解AOPAOP的实现原理 AOP代理模式静态代理动态代理1-JDK动态代理2-CGLIB动态代理 总结 理解AOP OOP - - Object Oriented Programming 面向对象编程 AOP - - Aspect Oriented Programming 面向切面编程 AOP是Spring提供的关键特性之一。AOP即面向切面编程&#xff0…