数据结构——队列(java实现)及相应的oj题

文章目录

  • 前言
  • 队列
    • 队列的概念
    • 队列的实现
      • 队列的链表实现
        • 实现的方法与属性
        • 内部类实现节点
        • 入队列
        • 出队列
        • 获取队头元素但不删除
        • 判空
        • 获取队列元素个数
      • 队列的数组实现
      • 循环队列
        • 方法属性实现:
        • 构造方法
        • 向循环队列插入一个元素,成功插入则为真。
        • 从循环队列中删除一个元素,成功删除则为真
        • 从队首获取元素,如果队列为空,返回-1
        • 获取队尾元素。如果队列为空,返回 -1
        • 检查循环队列是否为空
        • 判断循环队列是否已满
    • 双端队列(Deque)
    • 队列Oj题
      • 1. [用队列实现栈](https://leetcode-cn.com/problems/implement-stack-using-queues/)
      • 2. [用栈实现队列](https://leetcode-cn.com/problems/implement-queue-using-stacks/)


前言


队列

队列的概念

队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表,一种先进先出的数据结构。
队尾:允许插入的一端。
队头:允许删除的一端。

队列的实现

队列的层次实现可以是链表,也可以是数组。

队列的链表实现

队列
如果采用单链表实现,若使用头插与尾删,则出队的时间复杂度为O(n),若使用头删与尾插,且具有last标记(可看作指针),则时间复杂度为O(1).
如果采用双链表实现,则时间复杂度一定为O(1).

实现的方法与属性
public class MyQueue {ListNode first;   //创建指向队列首部的标记ListNode last;   //创建指向队列尾部的标记//入队列public void offer(int val) {}//出队列public int poll() {}//获取队头元素 但是不删除public int peek() { }//判空public boolean isEmpty() { } //获取队列元素个数public int size(){}      
}
内部类实现节点
 static  class  ListNode{//设定一个节点对象int data ;ListNode prev ;ListNode next;public ListNode(int data) {this.data = data;}}
入队列

实现思想:采用头插法,如果为空,则使得头标记与尾标记均指向新节点
不为空,则进行头插的操作。

   public void offer(int data) {//采用头插法ListNode cur = new ListNode(data);if(isEmpty()){first = last = cur;}else {cur.next = first;first.prev = cur;first = cur;}}
出队列

实现思路:

1 . 先判断队列是否为空,队列为空抛异常。
2. 队列不为空,将尾标记指向尾节点的前一个节点,然后将前一个节点的next指针置为空,删除尾结点。
因为我队入采取的是头插,所以队出采取尾删,如果大家采取尾插,则队出就采取头删了。

  public int poll() {try {if (isEmpty()) {throw new EmptyException("空队列异常!!!");}}catch (EmptyException e){e.printStackTrace();}int ret = last.data;last = last.prev;last.next = null;  // 删除尾结点return ret;}
获取队头元素但不删除

获取队头元素 但是不删除
实现思路:

1.先判断队列是否为空,队列为空抛异常。
2 .队列不为空,返回尾节点的数据。(因为我采取的是链表尾部的队首)

  public int peek() {//获取队头元素try {if (isEmpty()) {throw new EmptyException("空队列异常!!!");}}catch (EmptyException e){e.printStackTrace();}return last.data;}
判空

思想:直接返回头是否为空就行。

public boolean isEmpty(){return first == null;
}
获取队列元素个数

思想:直接遍历链表即可。

public int size(){//遍历整个链表ListNode cur = first;int count = 0 ;while (cur!=null){count++;cur = cur.next;}return  count;}

队列的数组实现

如果采用普通的数组实现队列,在下标大的一端进行插入数据,在下标小的一端删除数据,
在这里插入图片描述
我们可以在删除一个数据后,将所有的数据向左移动一位,但是时间复杂度就变成了O(N),能否用数组实现一个时间复杂度为O(1),则不浪费空间的队列呢?——即循环队列。

循环队列

循环队列图:
在这里插入图片描述
实现思想:我们有front标记指向队列的首部,用rear标记指向队列的尾部,用于指向要插入数据的位置,当下标的值超出数组长度时,便用求模计算找回对应的位置。

方法属性实现:
class MyCircularQueue {//实现的数组private  int[] elements;//指向首元素的标记int first = 0;//指向尾元素的标记int last = 0 ;//有效数组元素的个数int size = 0;//构造器,设置队列长度为 kpublic MyCircularQueue(int k) {}// 向循环队列插入一个元素。如果成功插入则返回真。public boolean enQueue(int value) {}//从循环队列中删除一个元素。如果成功删除则返回真。public boolean deQueue() {}//从队首获取元素。如果队列为空,返回 -1 public int Front() {}//获取队尾元素。如果队列为空,返回 -1 。public int Rear() {}//检查循环队列是否为空。public boolean isEmpty() {}//检查循环队列是否已满。public boolean isFull() {}
};
构造方法
 public MyCircularQueue(int k) {//用数组实现一个循环队列this.elements = new int[k];}
向循环队列插入一个元素,成功插入则为真。

实现思想:

  1. 判断队列是否已满,满了就返回false。
  2. 不满就在last处放。
  3. 在放完之后,将last的值+1然后模除队列的长度
 public boolean enQueue(int value) {//向循环队列中插入一个元素//先判断循环队列是否满if(isFull()){return false;}//未满this.elements[last] = value;last = (last+1)% elements.length;size ++;return true;}
从循环队列中删除一个元素,成功删除则为真

实现思想:

  1. 判断队列是否为空,空就返回false。
  2. 不空就直接将front指向下一个位置。
  3. 因为是循环队列,所以front+1再对数组长度进行求模。
public boolean deQueue() {//从队列中删除一个元素,删除队首的元素if(isEmpty()){return false;}//如果队列不为空,删除队首的元素,first+1,first = (first +1)% elements.length ; //必须保证first值到最大值时,能够再返回起点size = size-1;return true;}
从队首获取元素,如果队列为空,返回-1

实现思路:

  1. 先判断队列是否为空,为空返回-1。
  2. 不为空,返回front下标对应值。
  public int Front() {if(isEmpty()){return -1;}//如果队列不为空,返回队首元素return elements[first];}
获取队尾元素。如果队列为空,返回 -1

实现思想:

  1. 如果队列不为空,返回队尾元素
  2. 队尾元素的下标不一定为last -1 ,如果last 正好此时为0,那么last-1的结果为-1
    按照求模的方法:(last+数组长度-1)%数组长度,获取当前last之前的值
 public int Rear() {if(isEmpty()){return -1;}return elements[(last + elements.length-1 )%elements.length];}
检查循环队列是否为空

实现思想:通过size,判断size是否为0,来判断循环队列是否为空。

public boolean isEmpty() {//判断空,满足头标记与尾标记都相等,且无数值if( size ==0){return true;}return false;}
判断循环队列是否已满

实现思想:当front标记与last标记相同,且size不为0时,说明循环队列已满。

 public boolean isFull() {if(first ==last && size>0){return true;}return false;}
}

双端队列(Deque)

双端队列如图:
在这里插入图片描述
指可以两边都可以插入,都可以删除的队列。
Deque是一个接口,在java中有两个类实现了此接口

  1. ArrayDeque类,此类并没有在集合框架中
  2. LinkedList类
    ArrayDeque是双端队列的线性实现。
    LinkedList是双端队列的链式实现。

这两个类的对象可以当做栈与队列使用,因为他们实现了栈与队列的方法。

Deque<Integer> stack = new ArrayDeque<>();//双端队列的线性实现
Deque<Integer> queue = new LinkedList<>();//双端队列的链式实现

队列Oj题

1. 用队列实现栈

实现思想:
1 . 队列是先进先出操作,栈是先进后出,所以一个队列不可能实现栈,我们采用两个队列实现栈
2. 入栈,则直接将数据插入队列1即可
3. 出栈:将队列1中的size-1个元素,全部放入到队列2中去,剩余的一个元素,则进行出队即可。
如果再进行出栈,则将队2中的size-1个元素,放入到队1中去,将剩余的一个元素再进行出队
在这里插入图片描述

class MyStack {Queue<Integer> qu1 = new LinkedList<Integer>();Queue<Integer> qu2 = new LinkedList<Integer>();public MyStack() {}public void push(int x) {//将数据压入有数据的队列中if(!qu1.isEmpty()){qu1.offer(x);}else if(!qu2.isEmpty()){qu2.offer(x);}else{qu1.offer(x);}}public int pop() {//执行出栈操作,先判断栈是否为空if (empty()) {return -1;}//如果不为空if (!qu1.isEmpty()) {int len = qu1.size()-1;for (int i = 0; i < len; i++) {int val = qu1.poll();qu2.offer(val);}//return qu1.poll();}int len = qu2.size() -1 ;for (int i = 0; i < len; i++) {int val = qu2.poll();qu1.offer(val);}return qu2.poll();}public int top() {// 获取栈顶元素//将所有的数据转移到另一个队列中,期间经过一个临时变量,最后临时变量中的值即为栈顶元素if(empty()){return -1;}int val = 0;if(!qu1.isEmpty()){// for(int i=0;i<qu1.size();i++){ //有问题,当qu1执行poll方法后,会出现判断条件发生改变的情况while (!qu1.isEmpty()){val = qu1.poll();qu2.offer(val);}}else{while (!qu2.isEmpty()){val = qu2.poll();qu1.offer(val);}}return val;}public boolean empty() {if(qu1.isEmpty()&&qu2.isEmpty()){return true;}return false;}
}

2. 用栈实现队列

实现思想:

  1. 通过两个栈来实现队列
  2. 对于入队操作,直接将所有的数据放入栈1中即可
  3. 对于出队操作,则先判断栈2中是否有数据,如果有则出栈2的数据,如果没有,则将栈1中的全部数据转入栈2,然后再出栈2中的数据即可。
    在这里插入图片描述
class MyQueue {Stack<Integer> stack1 = new Stack<>();Stack<Integer> stack2 = new Stack<>();public MyQueue() {}public void push(int x) {//将所有的数据压入栈1stack1.push(x);}public int pop() {//先判断栈是否为空if(empty()){return -1;}if(!stack2.isEmpty()){//如果栈2不等于空,return stack2.pop();}//如果栈2为空while(!stack1.isEmpty()){//将栈1的元素全部压入栈2中去int val  =  stack1.pop();stack2.push(val);}return stack2.pop();}public int peek() {//获取栈顶的元素//先判断栈是否为空if(empty()){return -1;}if(!stack2.isEmpty()){//如果栈2不等于空,return stack2.peek();}//如果栈2为空while(!stack1.isEmpty()){//将栈1的元素全部压入栈2中去int val  =  stack1.pop();stack2.push(val);}return stack2.peek();}public boolean empty() {return stack1.isEmpty()==true && stack2.isEmpty() ==true ;}}

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

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

相关文章

Axivion Suite 7.8现已发布

现已实现100%覆盖MISRA规则&#xff0c;并加入了高级功能来提高代码分析能力。 我们很高兴地宣布Axivion Suite 7.8发布。全新版本的Axivion Suite对编译器、配置、分析、仪表板 (WebUI)和IDE插件的架构验证和静态代码分析功能均进行了升级。 100%覆盖所有可测试的MISRA规则 …

昇思25天学习打卡营第15天|K近邻算法实现红酒聚类

这个实验是关于如何使用MindSpore框架在红酒数据集上实现K近邻&#xff08;KNN&#xff09;算法来进行聚类分析的。KNN是一种简单但非常有效的机器学习算法&#xff0c;它通过计算样本之间的距离来决定其分类KNN算法的核心思想是&#xff0c;一个样本的类别可以通过它与训练集中…

Pytorch使用教学1-Tensor的创建

0 导读 在我们不知道什么是深度学习计算框架时&#xff0c;我们可以把PyTorch看做是Python的第三方库&#xff0c;在PyTorch中定义了适用于深度学习的张量Tensor&#xff0c;以及张量的各类计算。就相当于NumPy中定义的Array和对应的科学计算方法&#xff0c;正是这些基本数据…

【Nacos安装】

这里写目录标题 Nacos安装jar包启动Docker单体Docker集群 Nacos相关配置日志配置 Nacos安装 jar包启动 下载jar包 在官方下载链接&#xff0c;根据需求选择相应的版本下载。 解压 tar -zxvf nacos-server-2.4.0.1.tar.gz或者解压到指定目录 tar -zxvf nacos-server-2.4.0…

TikTok达人合作中的消费者行为研究:精准营销新趋势

随着全球社交媒体技术的飞速发展&#xff0c;TikTok作为短视频领域的佼佼者&#xff0c;其独特的达人带货模式不仅成为驱动消费市场发展的新力量&#xff0c;还深刻改变了消费者的购买行为。本文Nox聚星将和大家探讨TikTok达人合作过程中消费者的行为模式和偏好变化。 一、消费…

SkyWalking入门搭建【apache-skywalking-apm-10.0.0】

Java学习文档 视频讲解 文章目录 一、准备二、服务启动2-1、Nacos启动2-2、SkyWalking服务端启动2-3、SkyWalking控制台启动2-4、自定义服务接入 SkyWalking 三、常用监控3-1、服务请求通过率3-2、服务请求拓扑图3-3、链路 四、日志配置五、性能剖析六、数据持久化6-1、MySQL持…

企业怎么才能用上大语言模型?

题图&#xff5c;视觉中国 以ChatGPT为起点&#xff0c;大语言模型&#xff08;LLM&#xff09;用全面的技术创新&#xff0c;以及在用户和产业中的应用落地&#xff0c;再次掀起了一个AI新浪潮。 与它的前辈们相比&#xff0c;大语言模型因为打通了语言这一人类沟通中介&…

关联查询(xml)

多对多&#xff1a;数据库中需要有中间表&#xff0c;在两个实体类中都加入对方的List集合&#xff0c;在写查询语句时写三张表

MySQL第一阶段:多表查询、事务

继续我的MySQL之旅&#xff0c;继续上篇的DDL、DML、DQL、以及一些约束&#xff0c;该到了多表查询和事务的学习总结&#xff0c;以及相关的案例实现&#xff0c;为未来的复习以及深入的理解做好知识储备。 目录 多表查询 连接查询 内连接 外连接 子查询 事务 事务简介…

RTK高精度定位终端的功能跟用途

RTK高精度定位终端是一种集成了高精度定位技术的手持或便携式设备&#xff0c;其功能和用途广泛且重要。以下是RTK高精度定位终端的主要功能和用途&#xff1a; 一、功能 高精度定位&#xff1a; RTK技术通过接收卫星信号和地面基站的差分修正数据&#xff0c;实现厘米级甚至…

开源安全信息和事件管理(SIEM)平台OSSIM

简介 OSSIM&#xff0c;开源安全信息和事件管理&#xff08;SIEM&#xff09;产品&#xff0c;提供了经过验证的核心SIEM功能&#xff0c;包括事件收集、标准化和关联。 OSSIM作为一个开源平台&#xff0c;具有灵活性和可定制性高的优点&#xff0c;允许用户根据自己的特定需…

Java Linux操作系统

1、操作系统是协助用户调度硬件工作&#xff0c;充当用户和计算机硬件之间的桥梁 2、Linux内核 提供了linux系统的主要功能 3、发行版Centos&#xff1a;内核应用程序 4、快照&#xff1a;保存虚拟机的状态&#xff0c;当虚拟机出现问题的时候&#xff0c;可以恢复原始的状态…

华为强制恢复出厂设置后如何恢复数据?数据重生的2个方法介绍

华为作为全球知名的手机品牌&#xff0c;其产品在市场上广受欢迎。然而&#xff0c;有时由于各种原因&#xff0c;我们可能需要强制恢复出厂设置&#xff0c;这往往意味着数据的丢失。那么&#xff0c;如何在华为强制恢复出厂设置后&#xff0c;让数据“重生”呢&#xff1f;本…

Postman测试工具详细解读

目录 一、Postman的基本概念二、Postman的主要功能1. 请求构建2. 响应查看3. 断言与自动化测试4. 环境与变量5. 集合与文档化6. 与团队实时协作 三、Postman在API测试中的重要性1. 提高测试效率2. 保障API的稳定性3. 促进团队协作4. 生成文档与交流工具 四、Postman的使用技巧1…

Ubuntu24.04 deb文件 安装 MySQL8.4

Ubuntu24.04 deb文件 安装 MySQL8.4 ubuntu24.04 deb文件安装 MySQL8 升级系统 sudo apt update sudo apt -y dist-upgrade 安装常用工具 sudo apt -y install vim net-tools wget gcc make cmake lrzsz安装依赖 sudo apt -y install libmecab2 libjson-perl libaio1t64下载…

JavaEE - Spring Boot 简介

1.Maven 1.1 什么是Maven 翻译过来就是: Maven是⼀个项⽬管理⼯具。基于POM(Project Object Model,项⽬对象模型)的概念&#xff0c;Maven可以通 过⼀⼩段描述信息来管理项⽬的构建&#xff0c;报告和⽂档的项⽬管理⼯具软件。 可以理解为&#xff1a;Maven是一个项目管理工具…

关键词查找【Knuth-Morris-Pratt (KMP) 算法】

一个视频让你彻底学懂KMP算法_哔哩哔哩_bilibili KMP算法的核心是利用匹配失败后的信息&#xff0c;尽量减少模式串与主串的匹配次数以达到快速匹配的目的。 public class KMP {// 计算部分匹配表 (LPS)private static int[] computeLPSArray(String pattern) {int[] lps new…

Arduino学习笔记1——IDE安装与起步

一、IDE安装 去浏览器直接搜索Arduino官网&#xff0c;点击Software栏进入下载界面&#xff0c;选择Windows操作系统&#xff1a; 新版IDE下载不需要提前勾选所下载的拓展包&#xff0c;下载好后直接点击安装即可。 安装好后打开Arduino IDE&#xff0c;会自动开始下载所需的…

npm publish出错,‘proxy‘ config is set properly. See: ‘npm help config‘

问题&#xff1a;使用 npm publish发布项目依赖失败&#xff0c;报错 proxy config is set properly. See: npm help config 1、先查找一下自己的代理 npm config get proxy npm config get https-proxy npm config get registry2、然后将代理和缓存置空 方式一&#xff1a; …

基于TensorFlow.js和COCO-SsD模型的实时目标检测网络应用程序

基于TensorFlow.js和COCO-SsD模型的实时目标检测网络应用程序 实现流程 访问用户的桌面录屏并且显示视频源&#xff08;位置居中&#xff09;。对视频源进行实时目标检测。在检测到的目标周围绘制边界框&#xff0c;并用它们的类别和检测置信度进行标记。在视频源下方显示一个…