队列的算法

数组队列

数组的子集

主要方法addLast( )和removeFirst( )

public interface IQueueDesc<E>{
    void enqueue(E e);
    E    dequeue();
    E	 getFront();
    int  getSize();
    boolean isEmpty();
}

public class QueueMyList<E> implements IQueueDesc<E{
    MyArray<E> array;
    public QueueMyArray(){
        this(10);
    }
    public QueueMyArray(int capacity){
        array = new MyArray<>)(capacity);
    }
    // 入队
    public void enqueue(E e){
        array.addLast(e);
    }
    // 出队
    public E    dequeue(){
        array.removeFirst();
    }
    // 获取第一个元素
    public E    getFront(){
        array.getValueByInde(0);
    }
    public int    getSize(){
        return array.getSize();
    }
    public boolean    isEmpty(){
        return array.isEmpty();
    }
}
    

缺点:

①队首出列后,后面的全部向前移动一个补缺

②出队移动补缺麻烦 时间复杂度O(n)

解决方案

不要往前移动,减少复杂度,采用双指针,front和tail,就可以解决这个问题。

此时缺点:

如果不断入队和出队,前面就会空了一大截,前面一大片空间就浪费了。

循环队列

主要是尾指针移到末尾后又会移动到队首。

问题:

1.如何判断队列是空的?

front == tail,可能是空也可能是满,防止歧义,强行规定front == tail就是空!!!

2.如何判断队列是满的?

tail + 1 == front 就是满了,要浪费1个空格子

(tail + 1) % 数组长度 == front 队列为满

3.指针怎么指向

front指向队首,tail指向队尾的下一个存储单元

使用循环队列实现

初始化

public class QueueMyList<E> implements IQueueDesc<E>{
    private E[] data;
    private int size;

    private int front;
    private int tail;

    
    public QueueMyArray(){
        this(10);
    }
    public QueueMyArray(int capacity){
        // 要随时记得 我们自己定义的循环队列故意浪费了一个坑 所以要capacity+1
        this.data = (E[])new Object[capacity+1];
        //参数初始化
        this.size = 0;
        this.front = 0;
        this.tail = 0;
    }
    // 入队
    public void enqueue(E e){
        // 队列满了
        if(((tail+1) % data.length) == front){
            // 扩容
            resize(getCapacity()*2);
        }
        // 正常插入队里
        data[tail] = e;
        // 注意!!!!!!!这个地方容易出错 出界!不能用getCapacity
        tail = (tail+1) % data.length;
        size++;
    }
    // 出队
    public E dequeue(){
        if(isEmpty()){
            throw new RunTimeException("队列为空。。。");
        }
        size--;
        int result = data[front];
        // 记得处理游离对象!!!!!!!!!!!!!!!!!!!
        data[front] = null;
        front = (front+1) % data.length;
        // 缩容!!变成原来四分之一长度才缩容,要不到2如果缩容就变成 1/2 = 0 就缩没了
        // 如果设置一半会和getCapacity()/2 != 0有冲突 还要加判断麻烦
        if(size == getCapacity()/4 && getCapacity()/2 != 0){
            // 缩成原来一半
            resize(getCapacity()/2);
        }
        return result;
    }
    // 获取第一个元素
    public E  getFront(){
        if(isEmpty()){
            throw new RunTimeException("队列为空。。。");
        }
        return data[front];
    }
    public int getSize(){
        return  size;
    }
    public boolean isEmpty(){
        return tail == front;
    }
    public int getCapacity(){
        // 注意!!!!这点非常容易错
        return data.length - 1;
    }

    private void resize(int capacity){
        // 一定要记得+1啊!!!!!!!!!!!
        E[] newData = (E[])new Object[capacity+1];
        // 拷贝是全部移动到新数组的头部!!而不是原来位置
        for(int i=0;i < size;i++){
            newData[i] = data[front+i % data.length];
        }
        data = newData;
        front = 0;
        tail = size;
    }
}

数组队列先插10万个数,再出队10万个数耗时4.4秒

循环队列先插10万个数,再出队10万个数耗时0.01秒

改良【不浪费一个坑】

public interface ILoop<T>{
    void enqueue(T e);
    T dequeue();
    T peek();
    int getSize();
    boolean isEmpty();
    boolean isFull();
    void resize(int capacity);
}
public class MyLoopQueue<E> implements ILoopQueue<E>{
    private E[] data;
    private int size;
    private int capacity;
    private int front;
    private int tail;

    
    public QueueMyArray(){
        this(10);
    }
    public QueueMyArray(int capacity){
        // 这里没有浪费一个空间
        this.data = (E[])new Object[capacity];
        //参数初始化
        this.size = 0;
        this.front = 0;
        this.tail = 0;
        this.capacity = capacity;
    }
    // 入队
    public void enqueue(E e){
        // 队列满了 不用指针判断 用个数判断
        if(size == capacity){
            // 扩容
            resize(getCapacity()*2);
        }
        // 正常插入队里
        data[tail] = e;
        // 注意!!!!!!!这个地方容易出错 出界!不能用getCapacity
        tail = (tail+1) % data.length;
        size++;
    }
    // 出队
    public E dequeue(){
        if(size == 0){
            throw new RunTimeException("队列为空。。。");
        }
        size--;
        int result = data[front];
        // 记得处理游离对象!!!!!!!!!!!!!!!!!!!
        data[front] = null;
        front = (front+1) % data.length;
        // 缩容!!变成原来四分之一长度才缩容,要不到2如果缩容就变成 1/2 = 0 就缩没了
        // 如果设置一半会和getCapacity()/2 != 0有冲突 还要加判断麻烦
        if(size == getCapacity()/2){
            // 缩成原来一半
            resize(getCapacity()/2);
        }
        return result;
    }
    // 获取第一个元素
    public E  getFront(){
        if(isEmpty()){
            throw new RunTimeException("队列为空。。。");
        }
        return data[front];
    }
    public int getSize(){
        return  size;
    }
    public boolean isEmpty(){
        return tail == front;
    }
    public int getCapacity(){
        // 注意!!!!这点非常容易错
        return data.length - 1;
    }

    private void resize(int capacity){
        this.capacity = capacity;
        // 不需要加1 
        E[] newData = (E[])new Object[capacity];
        // 拷贝是全部移动到新数组的头部!!而不是原来位置
        for(int i=0;i < size;i++){
            newData[i] = data[front+i % data.length];
        }
        data = newData;
        front = 0;
        tail = size;
    }
}

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

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

相关文章

深度学习500问——Chapter03:深度学习基础(4)

文章目录 3.7 预训练与微调&#xff08;fine tuning&#xff09; 3.7.1 为什么无监督预训练可以帮助深度学习 3.7.2 什么是模型微调 fine tuning 3.7.3 微调时候网络参数是否更新 3.7.4 fine-tuning模型的三种状态 3.8 权重偏差和初始化 3.8.1 全都初始化为0 3.8.2 全都初始化为…

无需PS技能!2024年在线UI设计工具推荐,让你快速上手!

随着UI设计行业的蓬勃发展&#xff0c;越来越多的设计师进入UI设计&#xff0c;选择一个方便的UI设计工具尤为重要&#xff01;除了传统的UI设计工具外&#xff0c;在线UI设计工具也受到越来越多设计师的青睐。这种不受时间、地点和计算机配置限制的工作模式真的很令人兴奋。在…

回归预测 | Matlab实现SO-BP蛇算法优化BP神经网络多变量回归预测

回归预测 | Matlab实现SO-BP蛇算法优化BP神经网络多变量回归预测 目录 回归预测 | Matlab实现SO-BP蛇算法优化BP神经网络多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现SO-BP蛇算法优化BP神经网络多变量回归预测&#xff08;完整源码和数据) …

Figure 公司推出首款集成 OpenAI 大模型的自主人形机器人,开启与人类全面对话的新纪元

2024年3月13日&#xff0c;Figure&#xff0c;一家在人工智能机器人领域引领创新的公司&#xff0c;宣布推出了一款革命性的自主人形机器人。这款全新的 demo 机器人不仅标志着商业上可行的自主人形机器人技术的突破&#xff0c;更是通过整合 OpenAI 的先进大模型技术&#xff…

操作符详解(C语言)—算数操作符,移位操作符,位操作符

操作符的分类 算术操作符 移位操作符 位操作符 赋值操作符 单目操作符 关系操作符 逻辑操作符 条件操作符 逗号表达式 下标引用、函数调用和结构成员 算术操作符 - * / %除了 % 操作符之外&#xff0c;其他的几个操作符可以作用于整数和浮点数。对于 / 操作符如果两个…

Unity Mesh简化为Cube mesh

Mesh简化为Cube mesh &#x1f373;食用&#x1f959;子物体独立生成CubeMesh&#x1f96a;合并成一个CubeMesh&#x1f32d;Demo &#x1f373;食用 下载并导入插件&#x1f448;即可在代码中调用。 &#x1f959;子物体独立生成CubeMesh gameObject.ToCubeMesh_Invidual()…

关于 HTTP 协议,你了解多少?

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

数据分析的具体流程

1.导入 表格导入数据时要注意数据的格式问题非表格导入 可以先将文档放入word中 将换行符&#xff08;^p&#xff09;替换为|||&#xff0c;选择特殊格式中的段落标记 进行全部替换 以每一列最后的数据/平&#xff0c;作为换行的标志 将所整理的信息导入excel,对数据进行分列 选…

数据库系统概论-第5章 数据库完整性

5.1 实体完整性 5.2 参照完整性 5.3 用户定义完整性 5.4 完整性约束命名子句 5.5 域中的完整性限制 5.6 断言 5.7 触发器 5.8 小结

OpenGL+QT实现矢量和影像的叠加绘制

一、QT下OpenGL框架的初始化 OpenGL的介绍我在这里就没有必要介绍了&#xff0c;那OpenGL和QT的结合在这里就有必要先介绍一下&#xff0c;也就是怎么使用QT下的OpenGL框架。要想使用QT下的OpenGL框架&#xff0c;就必须要子类化QGLWidget&#xff0c;然后实现。 void initia…

冶炼金属 (第十四届蓝桥杯省赛C++ B组)详解(二分+推公式)

题目描述&#xff1a; 小蓝有一个神奇的炉子用于将普通金属 O 冶炼成为一种特殊金属 X。 这个炉子有一个称作转换率的属性 V&#xff0c;V 是一个正整数&#xff0c;这意味着消耗 V 个普通金属 O 恰好可以冶炼出一个特殊金属 X&#xff0c;当普通金属 O 的数目不足 V 时&#…

Spring MVC文件下载配置

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 文件下载 在Spring MVC中通常利用commons-io实现文件下载&#xff0c;示例代码如下&#xff1a; Controller RequestMapping("......") public class DownloadC…

AI大模型-Grok搭建

Grok搭建 硬件要求项目下载Checkpoint下载运行代码 马斯克又搞事情了&#xff0c;正式开源AI大模型Grok-1&#xff0c;免费还可商用&#xff0c;国内AI技术即将迎来重大突破。笔者简单整合了一下&#xff0c;如何搭建Grok-1的思路&#xff0c;供后期自己搭建以及读者学习使用。…

房屋租赁系统|基于JSP技术+ Mysql+Java+ B/S结构的房屋租赁系统设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;ssm&#xff0c;springboot的平台设计与实现项目系统开发资源&#xff08;可…

理解数据库习题

1.选择 &#xff08;1&#xff09;现实世界中客观存在并能相互区别的事物称为&#xff08; &#xff09;。 A.实体 B.实体集 C字段 D 记录 &#xff08;2&#xff09;下列实体类型的联系中&#xff0c;属于一对一联系的是&#xff08; &#xff09;A.教研室对教师的所属联系 …

centos 环境部署

一、安装redis 1. 升级 GCC 最直接的解决方式是升级你的 GCC 编译器到支持 C11 标准的版本。CentOS 7 默认的 GCC 版本较旧&#xff0c;可能不支持 _Atomic。你可以通过以下步骤升级 GCC&#xff1a; 启用 CentOS 的 Software Collections (SCL) 仓库&#xff0c;该仓库提供了…

力扣---完全平方数

思路&#xff1a; 还是比较好想的&#xff0c;g[i]定义为和为 i 的完全平方数的最少数量。那么递推关系式是g[i]min(g[i-1],g[i-4],g[i-9],...)1&#xff0c;数组初始化是g[0]0,g[1]1。注意这里要对g[0]初始化&#xff0c;&#xff08;举个例子&#xff09;因为在遍历到g[4]时&…

docker安装Milvus

docker安装Milvus 拉去CPU版本的milvus镜像 $ sudo docker pull milvusdb/milvus:0.10.0-cpu-d061620-5f3c00 docker pull milvusdb/milvus:0.10.0-cpu-d061620-5f3c00 mkdir -p milvus/conf cd milvus/conf ls wget https://raw.githubusercontent.com/milvus-io/milvus/v0.1…

未来教育趋势:AI个性化培训如何推动企业与员工共赢

AI定制学习&#xff1a;重新定义个性化员工培训的未来 随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;我们正目睹并亲历了AI在培训领域所引发的根本性变革。AI技术的整合不仅革新了知识传递的模式&#xff0c;而且重新塑造了个性化学习的内涵。依托于尖端算…

平替电容笔哪个品牌好?推荐五款 2024 高人气电容笔,入手不亏!

作为一名有着多年测评数码经验的评测师&#xff0c;用过的原装笔和平替电容笔加起来也有不下十款了&#xff0c;看过也有很多朋友因为选错电容笔&#xff0c;导致书写效率低&#xff0c;体验感差的例子也数不胜数。这并非夸大其词&#xff0c;因为不专业产品的最大弊端就是毫无…