【数据结构】_队列

news2024/11/17 10:36:35

目录

 1.概念

2.队列的使用

3.队列模拟实现

4.循环队列

5.双端队列

6.栈与队列的互相实现

6.1 用队列实现栈

6.2 用栈实现队列


 1.概念

(1)队列是只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表;

(2)队列具有先进先出,后进后出的特点;

(3)入队列:进行插入操作的一端称为队尾;

         出队列:进行删除操作的一端称为队头;

2.队列的使用

在java中,Queue是个接口,底层是通过链表实现的,其常用方法如下:

方法功能
boolean offer(E e)入队列
E poll()出队列
peek()获取队头元素
int size()获取队列中有效元素的个数
boolean isEmpty()检测队列是否为空

3.队列模拟实现

(1)包类关系:

(2)TestMyQueue:

package TestMyQueue;

import TestMyStack.EmptyException;

public class MyQueue {
    // 使用单链表实现队列
    static class Node{
        public int val;
        public Node next;
        public Node(int val){
            this.val = val;
        }
    }
    public Node head;
    public Node last;
    public int usedSize;
    public void offer(int val){
        Node newNode = new Node(val);
        if(head == null){
            head = newNode;
            last = newNode;
        }else{
            last.next = newNode;
            last = newNode;
            usedSize++;
        }
    }
    public int poll(){
        if(isEmpty()){
            throw new EmptyException();
        }
        int ret = head.val;
        head = head.next;
        return ret;
    }
    public boolean isEmpty(){
        return usedSize == 0;
    }
    public int peek(){
        if(isEmpty()){
            throw new EmptyException();
        }
        int ret = head.val;
        return ret;
    }
    public int getUseSize(){
        return usedSize;
    }
}

 (3)EmptyException:

package TestMyQueue;

public class EmptyException extends RuntimeException{
    public EmptyException(){

    }
}

4.循环队列

题目链接:622. 设计循环队列 - 力扣(LeetCode)

 代码:

class MyCircularQueue {
    private int[] elem;
    private int front;   // 表示队列的头
    private int rear;    // 表示队列的尾
    public MyCircularQueue(int k) {
        this.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 front == rear;
    }

    public boolean isFull() {
        // 写法1:
//        if( (rear+1) % elem.length == front){
//            return true;
//        }
//        return false;
        // 写法2:
        return (rear+1)% elem.length == front;
    }
}

5.双端队列

双端队列是指允许两端都可以进行入队和出队操作的队列;

Deque是一个接口,使用时必须创建其实现类类的对象:

常用的实现类为ArrayDeque(由数组实现的双端队列)和LinkedList(由双向链表实现的双端队列),故而实例化Deque的方式有以下两种: 

        // 链式双端队列
        Deque<Integer> deque = new LinkedList<>();
        // 数组双端队列
        Deque<Integer> deque2 = new ArrayDeque<>();

注:也可以使用Deque实现顺序栈:

实际上,以下写法:

Stack<Integer> stack = new Stack<>(); 

即:直接使用Stack类实例化栈对象是很少用的,可以使用ArrayDeque创建顺序栈对象:

Deque<Integer> stack2 = new ArrayDeque<>();

6.栈与队列的互相实现

6.1 用队列实现栈

题目链接:225. 用队列实现栈 - 力扣(LeetCode)

解题思路:使用两个队列实现栈,元素入栈至不为空的队列,元素出栈在不为空的队列出栈size-1个元素,最后余下的元素就是要出栈的元素;如果两个队列均为空,则入第一个队列;

代码:

public class MyStack {
    private Queue<Integer> queue1;
    private 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++){
           //for(int i=0;i<queue1.size()-1;i++){  //写法错误,poll会导致size变化
                int ret = queue1.poll();
                queue2.offer(ret);
            }
            return queue1.poll();
        }else{
            int size = queue2.size();
            for(int i=0;i<size-1;i++){
                int ret = queue2.poll();
                queue1.offer(ret);
            }
            return queue2.poll();
        }
    }

    public int top() {
        if(empty()){
            return -1;
        }
        if(!queue1.isEmpty()){
            int size = queue1.size();
            int ret = -1;
            for(int i=0;i<size;i++){
                ret = queue1.poll();
                queue2.offer(ret);
            }
            return ret;
        }else{
            int size = queue2.size();
            int ret = -1;
            for(int i=0;i<size;i++){
                ret = queue2.poll();
                queue1.offer(ret);
            }
            return ret;
        }
    }

    public boolean empty() {
        return queue1.isEmpty() && queue2.isEmpty();
    }
}

6.2 用栈实现队列

题目链接:232. 用栈实现队列 - 力扣(LeetCode)

解题思路:使用两个栈实现队列,stack1用于入栈元素,当需要出栈元素时,若stack2不为空,直接出栈stack2栈顶元素,如果stack2为空,就将stack1的所有元素入栈到stack2中,再出栈stack2顶元素即可;

代码:

class MyQueue {
    private Stack<Integer> stack1;
    private Stack<Integer> stack2;

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

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

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

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

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

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

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

相关文章

PyTorch深度学习实战(37)——CycleGAN详解与实现

PyTorch深度学习实战&#xff08;37&#xff09;——CycleGAN详解与实现 0. 前言1. CycleGAN 基本原理2. CycleGAN 模型分析3. 实现 CycleGAN小结系列链接 0. 前言 CycleGAN 是一种用于图像转换的生成对抗网络(Generative Adversarial Network, GAN)&#xff0c;可以在不需要配…

分布式事务-CAP定理+BASE理论+解决方案(两阶段提交+TCC事务)

事务就是指一个操作单元&#xff0c;操作单元中的所有操作要么同时成功要么同时失败。单体项目中的事务一般都是使用数据库提供的事务机制来完成的&#xff0c;但是分布式事务的事务参与者位于不同的节点上&#xff0c;也就是分布在不同的服务器上。分布式事务的最大问题就是各…

安卓游戏开发之音频技术优劣分析

一、引言 在安卓游戏开发中&#xff0c;音频处理技术扮演着至关重要的角色&#xff0c;它不仅能够增强游戏的沉浸感和玩家体验&#xff0c;还能通过声音效果传达关键的游戏信息。以下将对几种常见的安卓游戏音频处理技术进行优劣分析&#xff0c;并结合应用场景来阐述其特点。 …

Jmeter之内置函数__property和__P的区别

1. __property函数 作用 读取 Jmeter 属性 语法格式 ${__property(key,var,default)} 参数讲解 小栗子 ${__property(key)} 读取 key 属性如果找不到 key 属性&#xff0c;则返回 key&#xff08;属性名&#xff09; ${__property(key,,default)} 读取 key 属性如果找不到 k…

Linux内核中并发与竞争的处理方法之原子操作简介

一. 简介 当我们发现驱动程序中存在并发和竞争的时候一定要处理掉&#xff0c;接下来我们依次来学习一下 Linux 内核提供的几种并发和竞争的处理方法。 本文学习Linux内核提供的一种处理并发与竞争的方法&#xff1a;原子操作。 二. 原子操作简介 原子操作就是指不能再进一步…

【旧文更新】基于STM32L496的低功耗ADXL345加速度读取、TMP75温度检测

【旧文更新】基于STM32L496的低功耗ADXL345加速度读取、TMP75温度检测 文章目录 关于旧文新发加速度和温度检测附录&#xff1a;Cortex-M架构的SysTick系统定时器精准延时和MCU位带操作SysTick系统定时器精准延时延时函数阻塞延时非阻塞延时 位带操作位带代码位带宏定义总线函…

抖音小店怎么做起来?分享几种起店方式,新手商家认真选择!

大家好&#xff0c;我是电商糖果 网上关于抖音小店的起店方式有很多&#xff0c;有人说这种模式利润高&#xff0c;有人说这种模式长久。 东听一句&#xff0c;西听一句&#xff0c;让很多朋友感到比较迷茫。 根本不知道哪种方式更适合自己。 这里糖果就把网上最常见的五种…

线性代数:线性方程组解的结构

目录 齐次/非齐次方程组的解 Ax 0 的解的性质 定理 Ax b 的解的性质 相关证明 例1 例2 例3 齐次/非齐次方程组的解 Ax 0 的解的性质 定理 Ax b 的解的性质 相关证明 例1 例2 例3

2023年12月 Python(五级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,共50分) 第1题 下面代码的输出结果是?( ) dict1 = {1: 10, 2: 20, 3: 30} dict2 <

C#,大规模图(Large Graph)的均匀成本搜索之迪杰斯特拉(Dijkstra)算法与源代码

1 均匀成本搜索 均匀成本搜索是迪杰斯特拉算法的变体。这里&#xff0c;我们不是将所有顶点插入到一个优先级队列中&#xff0c;而是只插入源&#xff0c;然后在需要时一个接一个地插入。在每一步中&#xff0c;我们检查项目是否已经在优先级队列中(使用访问数组)。如果是&…

Day04 嵌入式---基本定时器

定时器概述 1、软件定时原理 使⽤纯软件的⽅式实现定时功能。 存在的问题&#xff1a;定时不太精准。CPU死等。 1&#xff09;压栈出栈需要花费时间 2&#xff09;ARM流⽔线体系架构的原因 2、定时器定时原理 使用精准的时基&#xff0c;通过硬件方式&#xff0c;实现定…

k-邻近算法(kNN)

目录 k-近邻算法概述 k-近邻算法的一般流程 kNN算法伪代码 k-近邻算法概述 优点&#xff1a;精度高、对异常值不敏感、无数据输入假定 缺点&#xff1a;计算复杂度高、空间复杂度高 适用数据范围&#xff1a;数值型和标称型 k-近邻算法的一般流程 &#xff08;1&#x…

mybatis数据操作语句

//基于注解 Mapper public interface reboudapt {Select("select * from dept")List<dept> huoqudept();//删除语句Delete("delete from dept where id #{id}")void deletesc(Integer id);//增加语句Insert("insert into dept(name, create_t…

Kubernetes服务网络Ingress网络模型分析、安装和高级用法

文章目录 1、Ingres简介2、Ingres网络模型分析3、安装Ingress4、使用4.1、搭建测试环境4.2、域名访问4.3、路径重写&#xff08;高级用法&#xff09;4.4、流量限制&#xff08;高级用法&#xff09; 5、总结 1、Ingres简介 Ingress翻译过来是“入口”的意思&#xff0c;也就是…

如何使用CanaryTokenScanner识别Microsoft Office文档中的Canary令牌和可疑URL

关于CanaryTokenScanner CanaryTokenScanner是一款功能强大的Canary令牌和可疑URL检测工具&#xff0c;该工具基于纯Python开发&#xff0c;可以帮助广大研究人员快速检测Microsoft Office和Zip压缩文件中的Canary令牌和可疑URL。 在网络安全领域中&#xff0c;保持警惕和主动…

小程序端学习

P2 创建Uni-app 分离窗口 一样的Ctrl S P3 细节知识点 创建新的小程序页面

Vulhub 练习 DC-4靶机完整复现

1.工具 kali:攻击机 IP地址&#xff1a;192.168.200.4 DC-4&#xff1a;靶机 IP地址&#xff1a;暂时未知 2.注意 这里搭建环境两台机器应该选用同类的网络连接方式&#xff1a;这里两台的连接方式为模式 二、信息收集 1.主机发现 找寻同网段下存活的主机&#xff08;可…

推荐几款项目经理常用的项目管理软件

随着科技的发展和项目需求&#xff0c;项目管理工具成为了确保工作顺利进行的关键。市场上有许多优秀的免费项目管理工具&#xff0c;它们功能强大、易于使用&#xff0c;并可以帮助团队更有效地规划、组织、执行和监控项目。以下是几款深受项目经理欢迎&#xff0c;好用且免费…

优化特征工程:创造性转换与有效处理

目录 前言1 利用领域知识2 多项式特征2.1 多项式特征的引入2.2 避免过拟合的策略2.3 模型解释性与多项式特征 3 缺失值处理3.1 填充缺失值的策略3.2 删除缺失值的考虑3.3 模型预测缺失值的应用 4 标准化和归一化4.1 标准化的应用4.2 归一化的适用场景4.3 特征缩放的注意事项 结…

【扩散模型:医学影像中的调查】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;深度学习 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 去噪扩散模型 去噪扩散模型是一类生成模型&#xff0c;最近在各种深度学习问题中引起了极大的兴趣。扩…