Java - 数据结构,队列

news2024/11/19 11:21:11

一、什么是队列

普通队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(FirstIn First Out) 入队列:进行插入操作的一端称为队尾(Tail/Rear) 出队列:进行删除操作的一端称为队头(Head/Front)
在这里插入图片描述
双端队列:可以在对头或者队尾进行插入或者删除操作。
在这里插入图片描述
普通队列和双端队列
在这里插入图片描述
从上面知道双向列表可以当普通队列使用,也可以当双端队列使用,也可以当栈使用。

二、队列常用的方法

2.1、Queue

在这里插入图片描述
注意add函数和offer函数
在这里插入图片描述

public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<>();
        queue.add(1);//添加元素
        queue.add(2);//添加元素
        queue.add(3);//添加元素
        queue.offer(4);//添加元素
        queue.offer(5);//添加元素
        queue.offer(6);//添加元素
        System.out.println(queue.peek());//获取对头元素,但是不删除
        System.out.println(queue.element());//获取对头元素,但是不删除
        System.out.println(queue.poll());//获取对头元素,并且删除对头元素
        System.out.println(queue.remove());//获取对头元素,并且删除对头元素
    }

2.2、Deque

在这里插入图片描述

public static void main(String[] args) {
        Deque<Integer> deque = new LinkedList<>();
        deque.add(1);//默认在队尾添加元素
        deque.addFirst(2);//在对头添加元素
        deque.addLast(3);//在队尾添加元素
        deque.offer(4);//在队尾添加元素
        deque.offerLast(5);//在队尾添加元素
        deque.offerFirst(6);//在队头添加元素
        System.out.println(deque);
        System.out.println(deque.peek());//获取元素,但是不删除
        System.out.println(deque.peekFirst());//获取队头元素,但是不删除
        System.out.println(deque.peekLast());//获取队尾元素,但是不删除
        System.out.println(deque.poll());//获取队头元素,并且删除
        System.out.println(deque.pollFirst());//获取队头元素,并且删除
        System.out.println(deque);
    }

三、单链表模拟实现队列

在这里插入图片描述
单链表可以实现队列,那双向链表也可以实现队列
使用单链表第三种方式实现队列
offer()- 在队列里面添加元素

/**
     * 在队列里面添加元素,实际上就是尾插法
     * @param val
     */
    public void offer(int val){
        //要插入节点,那就要先创造一个节点
        Node node = new Node(val);
        //这时候就要分两种情况:1、如果是第一次插入 2、不是第一次插入
        if(head == null){
            //head == null说明是第一次插入
            head = node;
            last = node;
        }else {
            last.next = node;
            last = last.next;
        }
    }

在这里插入图片描述

poll() - 出队列

/**
     * 出队列,并且删除元素
     * @return
     */
    public int poll(){
        //出队列就是删除头结点,但是如果链表里面没有节点那就不能删除
        if(isEmpty()){
            throw new RuntimeException("队列为空!");
        }
        int oldVal = head.val;
        head = head.next;
        return oldVal;
    }

    /**
     * 判断队列是否为空,如果队列为空那就返回true,否则返回FALSE
     * @return
     */
    public boolean isEmpty(){
        return this.head == null;
    }

使用的单链表实现简单的队列

//使用单链表实现队列,首先就要定义节点
class Node{
    //值域
    public int val;
    //指针域
    public Node next;
    public Node(int val){
        this.val = val ;
    }
}
public class MyQueue {
    //单链表实现队列,那就要加上一个尾指针
    public Node head;//头结点
    public Node last;//尾巴节点

    /**
     * 在队列里面添加元素,实际上就是尾插法
     * @param val
     */
    public void offer(int val){
        //要插入节点,那就要先创造一个节点
        Node node = new Node(val);
        //这时候就要分两种情况:1、如果是第一次插入 2、不是第一次插入
        if(head == null){
            //head == null说明是第一次插入
            head = node;
            last = node;
        }else {
            last.next = node;
            last = last.next;
        }
    }

    /**
     * 出队列,并且删除元素
     * @return
     */
    public int poll(){
        //出队列就是删除头结点,但是如果链表里面没有节点那就不能删除
        if(isEmpty()){
            throw new RuntimeException("队列为空!");
        }
        int oldVal = head.val;
        head = head.next;
        return oldVal;
    }

    /**
     * 判断队列是否为空,如果队列为空那就返回true,否则返回FALSE
     * @return
     */
    public boolean isEmpty(){
        return this.head == null;
    }

    /**
     * 获取对头的元素
     * @return
     */
    public int peek(){
        //出队列就是删除头结点,但是如果链表里面没有节点那就不能删除
        if(isEmpty()){
            throw new RuntimeException("队列为空!");
        }
        return head.val;
    }
}

四、循环队列

我们说了可以利用链表实现队列,那能不能利用数组实现队列???
在这里插入图片描述
上图转载于:https://blog.csdn.net/DarkAndGrey/article/details/122511544

队列面试题

设计循环队列

在这里插入图片描述
在这里插入图片描述
上图转载于:https://blog.csdn.net/DarkAndGrey/article/details/122511544

代码如下:

public class MyCircularQueue {
    //我们知道循环队列是有数组实现的,所以要创建一个数组,并且还有表示对头和队尾的下标
    public int[] elem;
    public int front;//对头的下标
    public int rear;//队尾的下标

    /**
     * 构造方法,初始化数组的大小
     * @param k
     */
    public MyCircularQueue(int k) {
        this.elem = new int[k+1];
    }

    /**
     * 入队列
     * @param value
     * @return
     */
    public boolean enQueue(int value) {
        //在入队列的时候先判断队列是否满,满了不能入
        if(isFull()){
            return false;
        }
        elem[rear] = value;
        rear = (rear+1) % elem.length;
        return true;
    }

    /**
     * 出队列
     * @return
     */
    public boolean deQueue() {
        if(isEmpty()){
            return false;
        }
        front = (front+1) % elem.length;
        return true;

    }

    /**
     * 返回对头下标的元素
     * @return
     */
    public int Front() {
        if(isEmpty()){
            return -1;
        }
        return elem[front];
    }

    /**
     * 获取队尾元素
     * @return
     */
    

    public int Rear() {
        if(isEmpty()){
            return -1;
        }
        int index = 0;
        if(rear == 0){
            index = elem.length - 1;
        }else{
            index = rear - 1;
        }
        return elem[index];
    }
    
    public boolean isEmpty() {
        //front的下一个是rear,那就说明空了
        return front == rear;
    }

    /**
     * 判断队列是否满
     * @return
     */
    public boolean isFull() {
        //rear的下一个如果是front,那这个队列就满了
        if((rear+1) % elem.length == front){
            return true;
        }
        return false;
    }
}

用队列实现栈

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

代码如下:

class MyStack {
    private Queue<Integer> qu1;
    private Queue<Integer> qu2;

    public MyStack() {
        qu1 = new LinkedList<>();
        qu2 = new LinkedList<>();
    }

    /**
     * 添加元素,将要添加的元素放入不为空的栈里面
     * @param x
     */
    public void push(int x) {
        if(!qu1.isEmpty()){
            //如果qu1不为空,那就插入元素
            qu1.offer(x);
        }else if(!qu2.isEmpty()){
            //如果qu2不为空,那就插入元素
            qu2.offer(x);
        }else{
            //第一次插入的时候,两个都为空的时候,那就指定队列插入元素
            qu1.offer(x);
        }
    }

    /**
     * 弹出元素
     * @return
     */
    public int pop() {
        if (empty()){
            return -1;
        }
        if(!qu1.isEmpty()){
            int size = qu1.size();
            for (int i = 0; i < size - 1; i++) {
                int val = qu1.poll();
                qu2.offer(val);
            }
            return qu1.poll();
        }
        if(!qu2.isEmpty()){
            int size = qu2.size();
            for (int i = 0; i < size - 1; i++) {
                int val = qu2.poll();
                qu1.offer(val);
            }
            return qu2.poll();
        }
        return -1;

    }

     public int top() {
        if (empty()){
            return -1;
        }
        if(!qu1.isEmpty()){
            int val = 0;
            //要记录这个size ,不然当出一个元素的时候这个函数都会变化,得到的值也会变化
            int size = qu1.size();
            for (int i = 0; i < size; i++) {
                val = qu1.poll();
                qu2.offer(val);
            }
            return val;
        }
        if(!qu2.isEmpty()){
            int val = 0;
            int size = qu2.size();
            for (int i = 0; i < size; i++) {
                val = qu2.poll();
                qu1.offer(val);
            }
            return val;
        }
        return -1;
    }

    public boolean empty() {
        return qu1.isEmpty() && qu2.isEmpty();
    }
}

用栈实现队列

在这里插入图片描述
栈 的特性是:先进后出。也就是说第一个入栈的数据,将是最后一个出栈,我们利用两个栈来实现这题。
在这里插入图片描述
代码如下:

class MyQueue {

    Stack<Integer> stack1;
    Stack<Integer> stack2;
    public MyQueue() {
        stack1 = new Stack<>();
        stack2 = new Stack<>();
    }

    public void push(int x) {
        stack1.push(x);
    }

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

    public int peek() {
        // 防止 别人一开始 就调用 peek,所以 peek 也需要 写 stack1 导入 stack2 的程序
        if(stack2.isEmpty()){
            while(!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
        }
        return stack2.peek();
    }

    public boolean empty() {// 如果模拟的队列 将全部数据出队,那么 stack1 和 stack2 都为空
        return stack1.isEmpty() && stack2.isEmpty();
    }
}

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

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

相关文章

【华为OD机试模拟题】用 C++ 实现 - 对称美学(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 获得完美走位(2023.Q1) 文章目录 最近更新的博客使用说明对称美学题目输入输出示例一输入输出说明示例二输入输出说明备注Code使用说明 参加华为od机试,一定要注意不要完全背诵代码࿰

五、DeepWalk、Node2Vec论文精读与代码实战【CS224W】(Datawhale组队学习)

开源内容&#xff1a;https://github.com/TommyZihao/zihao_course/tree/main/CS224W 子豪兄B 站视频&#xff1a;https://space.bilibili.com/1900783/channel/collectiondetail?sid915098 斯坦福官方课程主页&#xff1a;https://web.stanford.edu/class/cs224w 文章目录D…

拿下域控后,我还是对大佬的操作念念不忘

历来攻防演练中&#xff0c;我都笃信一个道理——吃饱了才有力气干活。所以&#xff0c;在清晨的客户现场&#xff0c;当看到大佬满意地吃完了我带来的煎饺&#xff0c;我知道这一战&#xff0c;我们作为攻击队&#xff0c;基本已经拿下了。 虽然说的每一句话都带着一股醋味儿…

Android 高工分享一波性能优化的总结~

随着 Android 开发越来越规范&#xff0c;国内工程师的素质&#xff0c;以及用户对产品的要求也越来越高。这也间接导致我们对研发项目的质量要求到了近乎苛刻的地步&#xff0c;**内存优化、UI 卡顿优化、App 崩溃监控等性能调优也逐渐成了人手必备的技能。**工作之余&#xf…

Boost资料整理备忘

Boost资料整理备忘 网络资源 书籍: The Boost C Libraries官方文档 Boost Library Documentation random boost.randomBoost随机库的简单使用&#xff1a;Boost.Random(STL通用)tutorialstd::random boost::asio Boost.Asio 网络编程 - 基本原理Boost.Asio DocBoost定时器 网…

理光M2701复印机载体初始化方法

理光M2701基本参数&#xff1a; 产品类型&#xff1a;数码复合机 颜色类型&#xff1a;黑白 复印速度&#xff1a;单面&#xff1a;27cpm 双面&#xff1a;16cpm 涵盖功能&#xff1a;复印、打印、扫描 网络功能&#xff1a;支持无线、有线网络打印 接口类型&#xff1a;USB2.0…

如何建立项目标准化评价体系?【锦狸】

PMO团队面临着管理多个项目&#xff0c;甚至是多个项目集&#xff0c;多个产品集的问题&#xff0c;那么如何对项目们进行标准化评价体系的建设&#xff0c;就是PMO需要首先思考的问题。 首先我们要关注项目的背景&#xff0c;了解了项目背景之后&#xff0c;我们才可以明确项…

CPython解释器性能分析与优化

原文来自微信公众号“编程语言Lab”&#xff1a;CPython 解释器性能分析与优化 搜索关注 “编程语言Lab”公众号&#xff08;HW-PLLab&#xff09;获取更多技术内容&#xff01; 欢迎加入 编程语言社区 SIG-元编程 参与交流讨论&#xff08;加入方式&#xff1a;添加文末小助手…

【Linux】使用U盘自动化安装Linux(VMware虚拟机)

文章目录前言一、准备二、新建虚拟机2.1 创建虚拟机2.2 新增硬盘2.3 系统启动项三、加电运行四、EFI方式五、总结前言 一、准备 基于之前的基础【Linux】Kickstart 配置U盘自动化安装Linux系统&#xff0c;现在我们可以在虚拟机中尝试自动化安装Linux系统。 二、新建虚拟机 …

POI导入导出、EasyExcel批量导入和分页导出

文件导入导出POI、EasyExcel POI&#xff1a;消耗内存非常大&#xff0c;在线上发生过堆内存溢出OOM&#xff1b;在导出大数据量的记录的时候也会造成堆溢出甚至宕机&#xff0c;如果导入导出数据量小的话还是考虑的&#xff0c;下面简单介绍POI怎么使用 POI导入 首先拿到文…

Java:如何选择一个Java API框架

Java编程语言是一种高级的、面向对象的语言&#xff0c;它使开发人员能够创建健壮的、可重用的代码。Java以其可移植性和平台独立性而闻名&#xff0c;这意味着Java代码可以在任何支持Java运行时环境(JRE)的系统上运行。Java和Node js一样&#xff0c;是一种功能强大的通用编程…

机试指南

文章目录零、绪论和IDE安装int取值范围常犯的编程小错误一、枚举和模拟 (暴力求解)(一) 枚举1.Reverse函数 求 反序数2.程序出错的原因1.编译错误 (compile)&#xff1a;基本语法错误2.链接错误 (link)&#xff1a;函数名写错了3.运行错误 (run)&#xff1a;结果与预期不符&…

前后端分离开发Springboot+VUE学习笔记

学习内容来源&#xff1a;传送门 目录前后端分离实现技术创建vue项目在idea中打开新建页面创建SpringBoot应用创建实体对象与数据库表元素绑定创建实体类接口前端调用数据跨域传输在springboot中解决总结前后端分离 前后端分离就是将一个应用的前端和后端代码分开写&#xff0…

前端:分享JS中7个高频的工具函数

目录 ◆1、将数字转换为货币 ◆2、将 HTML 字符串转换为 DOM 对象 ◆3、防抖 ◆4、日期验证 ◆5、将 FormData&#xff08;表单数据&#xff09;转换为 JSON ◆6、衡量一个函数的性能 ◆7、从数组中删除重复项 JavaScript 实用函数是有用的、可重复使用的片段&#xff0…

STM32开发(14)----CubeMX配置ADC

CubeMX配置ADC前言一、什么是ADC&#xff1f;二、实验过程1.单通道ADC采集STM32CubeMX配置代码实现2.多通道ADC采样(非DMA)STM32CubeMX配置代码实现3.多通道ADC采样&#xff08;DMA&#xff09;STM32CubeMX配置代码实现总结前言 本章介绍使用STM32CubeMX对ADC进行配置的方法&a…

SpringCloud之Seata(二)

4.Seata如何应用于项目&#xff1f; 安装seata及修改配置 4.1 官网下载Seata安装包 4.2 修改seata/config.txt 4.2.1 修改存储方式 store.db.dbTypemysql store.db.driverClassNamecom.mysql.jdbc.Driver store.db.urljdbc:mysql://你的IP:3306/seata?useUnicodetrue sto…

第一篇博客------自我介绍篇

目录&#x1f506;自我介绍&#x1f506;学习目标&#x1f506;如何学习单片机Part 1 基础理论知识学习Part 2 单片机实践Part 3 单片机硬件设计&#x1f506;希望进入的公司&#x1f506;结束语&#x1f506;自我介绍 Hello!!!我是一名即已经步入大二的计算机小白。 --------…

F4—LVDS接口LCD显示彩图测试-2023-02-25

1.简介 系列文章TFT彩条测试介绍到&#xff0c;屏幕是由厂家提供的TFT显示模组和屏幕PCB背板组成。PCB的作用是提供LCD背光所需的电压、用于屏幕显示的电压、与其他设备相连的排针或者其他连接器形式。当模组支持触摸功能时还可以接上触摸转换或触摸控制芯片&#xff0c;通过SP…

Qt 中的XML

XML的基本介绍&#xff1a; 在前端开发中&#xff1a;HTML是用来显示数据&#xff0c;而XML是用来传输和存储数据的 XML 指可扩展标记语言&#xff08;EXtensible Markup Language&#xff09;XML 是一种标记语言&#xff0c;很类似 HTMLXML 的设计宗旨是传输数据&#xff0c;而…

超简单的待办事项列表管理器todo

什么是 todo ? todo 是一个自托管的 todo web 应用程序&#xff0c;可让您以简单且最少的方式跟踪您的 todo。&#x1f4dd; 老苏觉得和之前介绍的 KissLists 比较像 文章传送门&#xff1a;最简单的共享列表服务器KissLists 官方提供了 Demo 演示站点&#xff1a;https://tod…