当前位置: 首页 > news >正文

java详解队列

在这里插入图片描述

文章目录

  • 一、队列是什么?
  • 二、模拟实现队列
  • 三、模拟实现循环队列
  • 四、用队列实现栈
  • 五、用栈实现队列

一、队列是什么?

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾(Tail/Rear) 出队列:进行删除操作的一端称为队头(Head/Front)
在这里插入图片描述
在这里插入图片描述
队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作。
LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用。

二、模拟实现队列

队列中既然可以存储元素,那底层肯定要有能够保存元素的空间,通过前面线性表的学习了解到常见的空间类型有两种:顺序结构 和 链式结构。同学们思考下:队列的实现使用顺序结构还是链式结构好?
因为队列是一种先进先出的数据结构,顺序表要想达到此目的,删除和取数据时间复杂度达到了O(n),那我们可不可以用单链表而且时间复杂度是O(1)呢?

public class MyQueue {
    static class ListNode {
        public int value;
        public ListNode next;

        public ListNode(int value) {
            this.value = value;
        }
    }
    public ListNode head;
    public ListNode tail;

    //入队列
    public void offer(int data) {
        ListNode node = new ListNode(data);
        if(head == null) {
            head = node;
            tail = node;
            return;
        }
        tail.next = node;
        tail = node;
    }

    //出队列
    public int poll() {
        if(isEmpty()) {
            return -1;
        }
        int ret = head.value;
        head = head.next;
        if(head == null) {
            tail = null;
        }
        return ret;
    }

    //查看队列第一个元素
    public int peek() {
        if(isEmpty()) {
            return -1;
        }
        int ret = head.value;
        return ret;
    }

    //判断队列是否为空
    public boolean isEmpty() {
        return size() == 0;
    }

    //获取队列大小
    public int size() {
        ListNode cur = head;
        int count = 0;
        while (cur != null) {
            cur = cur.next;
            count++;
        }
        return count;
    }
}

在这里插入图片描述

三、模拟实现循环队列

循环队列是把顺序队列首尾相连,把存储队列元素的表从逻辑上看成一个环,成为循环队列。
在这里插入图片描述
在实现循环队列时,我们主要面临的问题是,什么情况下队列为空,什么情况下队列为满,在判断满时:我们有两种方案,定义一个size变量,如果等于0为空,等于队列容量为满,这种过于简单,我们采用浪费一个空间的办法,如果head == tail队列为空,如果tail的下一个位置为head为满。

class MyCircularQueue {
    public int[] arr;
    public MyCircularQueue(int k) {
        arr = new int[k+1];
    }
    public int front;
    public int rear;
    public boolean enQueue(int value) {
        if(isFull()) {
            return false;
        }
        arr[rear] = value;
        rear = (rear + 1) % arr.length;
        return true;
    }

    public boolean deQueue() {
        if(isEmpty()) {
            return false;
        }
        front = (front + 1) % arr.length;
        return true;
    }

    public int Front() {
        if(!isEmpty()) {
            return arr[front];
        }
        return -1;
    }

    public int Rear() {
        if(!isEmpty()) {
            int ret = rear == 0 ? arr.length - 1 : rear - 1;
            return arr[ret];
        }
        return -1;
    }

    public boolean isEmpty() {
        return front == rear;
    }

    public boolean isFull() {
        return (rear + 1) % arr.length == front;
    }
}

四、用队列实现栈

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
在这里插入图片描述

import java.util.LinkedList;
import java.util.Queue;

class MyStack {
    public Queue<Integer> qu1;
    public Queue<Integer> qu2;
    public MyStack() {
        qu1 = new LinkedList<>();
        qu2 = new LinkedList<>();
    }
    
    public void push(int x) {
        if(empty()) {
            qu1.offer(x);
            return;
        }
        if(qu1.isEmpty()) {
            qu2.offer(x);
        }else {
            qu1.offer(x);
        }
    }
    
    public int pop() {
        if(empty()) {
            return -1;
        }
        if(qu1.isEmpty()) {
            int x = qu2.size();
            for (int i = 0; i < x - 1; i++) {
                qu1.offer(qu2.poll());
            }
            return qu2.poll();
        }else {
            int x = qu1.size();
            for (int i = 0; i < x - 1; i++) {
                qu2.offer(qu1.poll());
            }
            return qu1.poll();
        }
    }
    
    public int top() {
        if(empty()) {
            return -1;
        }
        if(qu1.isEmpty()) {
            int x = qu2.size();
            for (int i = 0; i < x - 1; i++) {
                qu1.offer(qu2.poll());
            }
            int ret = qu2.poll();
            qu1.offer(ret);
            return ret;
        }else {
            int x = qu1.size();
            for (int i = 0; i < x - 1; i++) {
                qu2.offer(qu1.poll());
            }
            int ret = qu1.poll();
            qu2.offer(ret);
            return ret;
        }
    }
    
    public boolean empty() {
        return qu1.isEmpty() && qu2.isEmpty();
    }
}

五、用栈实现队列

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
在这里插入图片描述

import java.util.Stack;

class MyQueue{
    public Stack<Integer> s1;
    public Stack<Integer> s2;

    public MyQueue() {
        s1 = new Stack<>();
        s2 = new Stack<>();
    }
    
    public void push(int x) {
        s1.push(x);
    }
    
    public int pop() {
        if(empty()) {
            return -1;
        }
        if(!s2.empty()) {
            return s2.pop();
        }else {
            while(!s1.empty()) {
                s2.push(s1.pop());
            }
            return s2.pop();
        }
    }
    
    public int peek() {
        if(empty()) {
            return -1;
        }
        if(!s2.empty()) {
            return s2.peek();
        }else {
            while(!s1.empty()) {
                s2.push(s1.pop());
            }
            return s2.peek();
        }
    }
    
    public boolean empty() {
        return s1.empty() && s2.empty();
    }
}

相关文章:

  • springboot - 2.7.3版本 - (八)ELK整合Kafka
  • uniCloud开发公众号:一、接收、解析、组装xml消息
  • YOLO系列目标检测算法-YOLOv1
  • JavaScript高级,ES6 笔记 第三天
  • 【雷达图】R语言绘制雷达图(ggradar),NBA季后赛数据为例
  • 机器学习笔记 - 在QT/PyTorch/C++ 中加载 TORCHSCRIPT 模型
  • redis 技术分享
  • 怎么让面试官喜欢你?
  • 深度学习模型理解-CNN-手写数据字代码
  • C# ZBar解码测试(QRCode、一维码条码)并记录里面隐藏的坑
  • 【技术美术图形部分】图形渲染管线3.0-光栅化和像素处理阶段
  • css:一个容器(页面),里面有两个div左右摆放并且高度和容器高度一致,左div不会随着页面左右伸缩而变化,右div随页面左右伸缩宽度自适应(手写)
  • Kubernetes 1.25 集群搭建
  • 【每周CV论文推荐】GAN在医学图像生成与增强中的典型应用
  • python毕业设计项目源码选题(16)跳蚤市场二手物品交易系统毕业设计毕设作品开题报告开题答辩PPT
  • [译] React v16.8: 含有Hooks的版本
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • Bootstrap JS插件Alert源码分析
  • Magento 1.x 中文订单打印乱码
  • React 快速上手 - 07 前端路由 react-router
  • vue总结
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 阿里云购买磁盘后挂载
  • 百度小程序遇到的问题
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 后端_ThinkPHP5
  • 网页视频流m3u8/ts视频下载
  • 我是如何设计 Upload 上传组件的
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (4) PIVOT 和 UPIVOT 的使用
  • (分布式缓存)Redis持久化
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (转)菜鸟学数据库(三)——存储过程
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • .Family_物联网
  • .NET CLR基本术语
  • .net core 连接数据库,通过数据库生成Modell
  • .NET 解决重复提交问题
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .net6+aspose.words导出word并转pdf
  • .NET开源项目介绍及资源推荐:数据持久层 (微软MVP写作)
  • .NET框架设计—常被忽视的C#设计技巧
  • .skip() 和 .only() 的使用
  • @AutoConfigurationPackage的使用
  • @property括号内属性讲解
  • [ vulhub漏洞复现篇 ] JBOSS AS 5.x/6.x反序列化远程代码执行漏洞CVE-2017-12149
  • [.net]官方水晶报表的使用以演示下载
  • []指针
  • [<事务专题>]
  • [Angular] 笔记 18:Angular Router