Java(二十二)---队列

news2024/11/14 21:39:40

文章目录

  • 前言
  • 1.队列(Queue)的概念
  • 2.Queue的使用
  • 3.队列的模拟实现
  • 4.循环队列
  • 5.双端队列
  • 6.面试题
    • [1. 用队列实现栈](https://leetcode.cn/problems/implement-stack-using-queues/description/)
    • [2. 用栈实现队列](https://leetcode.cn/problems/implement-queue-using-stacks/description/)


前言

上一篇我们学习了栈(Stack) ,现在讲队列(Queue)。


1.队列(Queue)的概念

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾(Tail/Rear) 出队列:进行删除操作的一端称为队头(Head/Front)
在这里插入图片描述


2.Queue的使用

在Java中,Queue是个接口,底层是通过链表实现的。
在这里插入图片描述

在这里插入图片描述

    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        queue.offer(4);
        queue.offer(5); // 从队尾入队列
        System.out.println(queue.size());
        System.out.println(queue.peek()); // 获取队头元素
        queue.poll();
        System.out.println(queue.poll()); // 从队头出队列,并将删除的元素返回
        if(queue.isEmpty()){
            System.out.println("队列空");
        }else{
            System.out.println(queue.size());
        }
    }

3.队列的模拟实现

队列中既然可以存储元素,那底层肯定要有能够保存元素的空间,通过前面线性表的学习了解到常见的空间类型有两种:顺序结构链式结构。思考下:队列的实现使用顺序结构还是链式结构好?
在这里插入图片描述

public class MyQueue {
    static class ListNode{
        public int val;
        public ListNode prev;
        public ListNode next;

        public ListNode(int val) {
            this.val = val;
        }
    }
    public ListNode first;
    public ListNode last;
    public int usedSize = 0;
    public void offer(int data){
        ListNode node = new ListNode(data);
        if (isEmpty()){
            first = last = node;
        }else {
            last.next = node;
            node.prev = last;
            last = node;
        }
        this.usedSize++;
    }
    public int poll(){
        if (isEmpty()){
            return -1;
        }
        int val = first.val;
        first = first.next;
        if (first!=null){
            first.prev = null;
        }
        this.usedSize--;
        return val;
    }
    public int peek(){
        if (isEmpty()){
            return -1;
        }
        return first.val;
    }
    public boolean isEmpty(){
        return usedSize == 0;
    }
}

4.循环队列

如何使用顺序表来模拟队列?
使用循环队列
实际中我们有时还会使用一种队列叫循环队列。如操作系统课程讲解生产者消费者模型时可以就会使用循环队列。环形队列通常使用数组实现。

在这里插入图片描述
有下面三个问题需要先解决:

  1. 怎么判断数组已经满了?
  2. 怎么判断数组是空的?
  3. 如何使数组下标进行循环?

在这里插入图片描述

在这我们使用方案二进行操作。
设计循环队列

class MyCircularQueue {
    public int rear;
    public int front;
    public int[]elem;
    public MyCircularQueue(int k) {
        elem = new int[k+1];
    }
    
    public boolean enQueue(int value) {
        if (isFull()){
            return false;
        }
        elem[rear] = value;
        rear = (rear + 1) % elem.length;
        return true;
    }
    
    public boolean deQueue() {
        if (isEmpty()){
            return false;
        }
        front = (front + 1) % elem.length;
        return true;
    }
    
    public int Front() {
        if (isEmpty()){
            return -1;
        }
        return elem[front];
    }
    
    public int Rear() {
        if (isEmpty()){
            return -1;
        }
        int index = (rear == 0)? elem.length-1 : rear - 1;
        return elem[index];
    }
    
    public boolean isEmpty() {
        return rear == front;
    }
    
    public boolean isFull() {
        return (rear+1)%elem.length == front;
    }
}

5.双端队列

双端队列(deque)是指允许两端都可以进行入队和出队操作的队列,deque 是 “double ended queue” 的简称。
那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。

在这里插入图片描述
Deque是一个接口,使用时必须创建LinkedList的对象。

在实际工程中,使用Deque接口是比较多的,栈和队列均可以使用该接口

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

6.面试题

1. 用队列实现栈

在这里插入图片描述
在这里插入图片描述

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

2. 用栈实现队列

在这里插入图片描述

在这里插入图片描述

class MyQueue {
    public ArrayDeque<Integer> stack1;
    public ArrayDeque<Integer> stack2;
    public MyQueue() {
        stack1 = new ArrayDeque();
        stack2 = new ArrayDeque();
    }
    
    public void push(int x) {
        stack1.push(x);        
    }
    
    public int pop() {
        if (empty()){
            return -1;
        }
        if (stack2.isEmpty()){
            while(!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
        }
        return stack2.pop();

    }
    
    public int peek() {
        if (empty()){
            return -1;
        }
        if (stack2.isEmpty()){
            while(!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
        }
        return stack2.peek();


    }
    
    public boolean empty() {
        return stack1.isEmpty()&&stack2.isEmpty();
    }
}

下一篇便要进入现阶段比较难的二叉树的部分,大家做好准备,开干!

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

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

相关文章

VPN以及GRE和MGRE

VPN VPN — 是虚拟专用网络 通俗地说&#xff0c;就是通过虚拟的手段&#xff0c;将两个独立的网络&#xff0c;穿越一个公共网络进行连接&#xff0c;实现点到点专线的效果&#xff08;可以理解为&#xff1a;一个分公司通过公网和总公司建立点到点的专线连接&#xff09; 现…

innovus:如何获取clock net的route_type和clock name

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 clock net的route type分为top trunk和leaf,net_type的设置方式见文章:

【06】LLaMA-Factory微调大模型——微调模型评估

上文【05】LLaMA-Factory微调大模型——初尝微调模型&#xff0c;对LLama-3与Qwen-2进行了指令微调&#xff0c;本文则介绍如何对微调后的模型进行评估分析。 一、部署微调后的LLama-3模型 激活虚拟环境&#xff0c;打开LLaMA-Factory的webui页面 conda activate GLM cd LLa…

汇编实验5

本实验在32位Linux虚拟机中完成&#xff08;点击查看安装教程&#xff09; 实验内容 二进制炸弹实际是由C语言源程序生成的可执行目标代码&#xff0c;主程序可参考bomb.c。运行时&#xff0c;会按次序提示用户输入3个不同的字符串。如果输入的字符串有误&#xff0c;炸弹就会…

结合金融场景的Scipy模块编程

结合金融场景的Scipy模块编程 数据链接&#xff1a;https://pan.baidu.com/s/1VMh8-4IeCUYXB9p3rL45qw 提取码&#xff1a;c6ys import numpy as np import pandas as pd import statsmodels import matplotlib.pyplot as plt from pylab import mpl mpl.rcParams[font.sans-se…

4 C 语言控制流与循环结构的深入解读

目录 1 复杂表达式的计算过程 2 if-else语句 2.1 基本结构及示例 2.2 if-else if 多分支 2.3 嵌套 if-else 2.4 悬空的 else 2.5 注意事项 2.5.1 if 后面不要加分号 2.5.2 省略 else 2.5.3 省略 {} 2.5.4 注意点 3 while 循环 3.1 一般形式 3.2 流程特点 3.3 注…

SaaS的“大模型焦虑”

随着大模型技术的兴起&#xff0c;SaaS行业正面临前所未有的机遇与挑战。本文深入剖析了SaaS厂商在AI化升级过程中的’大模型焦虑’&#xff0c;并探讨了如何通过战略性的AI应用找到自信&#xff0c;实现产品与服务的转型升级&#xff0c;为SaaS行业的AI之路提供了宝贵的思考与…

JVM之运行时数据区(一):程序计数器+本地方法栈

JVM之运行时数据区&#xff08;一&#xff09;&#xff1a;程序计数器本地方法栈 1.运行时数据区概述2.程序计数器作用特点常见问题 3.本地方法接口本地方法本地接口 4.本地方法栈特点 1.运行时数据区概述 Java虚拟机定义了若干种程序运行期间会使用到的运行时数据区其中有一些…

昇思25天学习打卡营第30天 | MindNLP ChatGLM-6B StreamChat

今天是第30天&#xff0c;学习了MindNLP ChatGLM-6B StreamChat。 今天是参加打卡活动的最后一天&#xff0c;经过这些日子的测试&#xff0c;昇思MindSpore效果还是不错的。 ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型&#xff0c;具有62亿参数&#xff0c;基于 …

业务系统核心模块资料访问性能优化实战

随着业务系统的云化转型不断推进&#xff0c;业务量呈现显著增长&#xff0c;对业务系统的性能和资源管理提出了更高要求。在这样的背景下&#xff0c;实现系统资源使用与性能指标的均衡成为保障生产系统高效稳定运行的核心任务。 在性能优化的范畴内&#xff0c;核心业务系统对…

Linux 10:进程信号

信号示例&#xff1a; 用户输入命令,在Shell下启动一个前台进程&#xff1a; 用户按[CtrlC]&#xff0c;这个键盘输入产生一个硬件中断&#xff0c;被OS获取&#xff0c;解释成信号&#xff0c;发送给目标前台进程。前台进程因为收到信号&#xff0c;进而引起进程退出。 注意&…

2048小游戏,h5,纯前端

部分代码 //scorevar scoreSprite game.add.sprite(10, 10);var scoreGraphics game.add.graphics(0, 0);scoreGraphics.lineStyle(5, 0xA1C5C5);scoreGraphics.beginFill(0x308C8C);scoreGraphics.drawRoundedRect(0, 0, 70, 50, 10);scoreGraphics.endFill();scoreSprite.a…

端到端语音识别

端到端语音识别 一.端到端语音识别的动机 1.传统语音识别语言模型训练 2.传统语音识别缺点 流程复杂且繁琐&#xff1a; 传统的语音识别系统涉及的流程非常多且复杂&#xff0c;从数据准备、模型训练到最终的系统集成&#xff0c;每个步骤都需要仔细处理。入门门槛高&#x…

WEB前端07-DOM对象

DOM模型 1.DOM概念 文档对象模型属于BOM的一 部分&#xff0c;用于对BOM中的核心对象document进行操作&#xff0c;它是一种与平台、语言无关的接口&#xff0c;允许程序和脚本动态地访问或更新HTML、XML文档的内容、结构和样式&#xff0c;且提供了一系列的函数和对象来实现…

近几天,北京大学副校长、教务长王博亲自为藏族女孩送上北京大学首封录取通知书!

藏族女孩代吉永措收到了北京大学2024年首封本科录取通知书。她来自青海湟川中学&#xff0c;已被北京大学历史学科强基计划录取&#xff0c;即将就读于北京大学历史学系。北京大学副校长、教务长王博亲自为代吉永措送上了这份录取通知书&#xff0c;并与她亲切交流了未来的学习…

Linux介绍和文件管理

一Linux的起源 1.Unix Dennis Ritchie和Ken Thompson发明了C语言&#xff0c;而后写出了Unix的内核 2.Minix MINIX是一种基于微 内核架构的类UNIX计算机操作系统&#xff0c;由 Andrew S. Tanenbaum发明 3.Linux内核 芬兰赫尔辛基大学的研究生Linus Torvalds基于Gcc、 ba…

注册安全分析报告:OneApm

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …

C语言 ——— 打印水仙花数

目录 何为水仙花数 题目要求 代码实现 何为水仙花数 “水仙花数”是指一个n位数&#xff0c;其各位数字的n次方之和等于该数本身 如&#xff1a;153 1^3 5^3 3^3&#xff0c;则153就是一个“水仙花数” 题目要求 求出0~100000的所有“水仙花数”并输出 代码实现 #i…

万字 AI 干货及感悟分享

最近一直在研究 AI Agent 在零代码平台中的应用, 特地研究并总结了一份AI学习的干货, 方便大家快速理解LLM, 并熟悉主流的AI大模型框架, 以及如何基于AI, 来改善我们传统的工作模式. 上面是本文的核心大纲, 接下来开始我的分享和总结. LLM介绍 1. LLM概念 大语言模型&#x…

【安当产品应用案例100集】001 — 基于UKEY的文件加密流转

随着企业信息化程度的不断提高&#xff0c;数据已成为企业最重要的资产之一。然而&#xff0c;数据泄露的风险也随之增加。数据泄露可能导致企业商业机密泄露、客户隐私泄露、经济损失以及法律诉讼等一系列严重后果。因此&#xff0c;保护数据安全已成为企业不可忽视的重要任务…