Java数据结构---栈和队列

目录

栈(Stack)

队列(Queue)

循环队列


栈(Stack)

  :一种特殊的线性表,其只允许在固定的一端进行插入和删除操作元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In Out)的原则。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶

出栈:栈的删除操作叫做出栈。出数据在栈顶

可以将栈类比为枪的弹匣,先进弹夹的子弹后打出。

java中提供了Stack类来实现栈。Stack包括以下方法:

以下是栈的模拟实现:

package MyStack;

import java.util.Arrays;

public class MyStack {
     public int[] elem;
     public int usedSize;

     public static final  int DEFAULT_CAPACITY = 10;
     public MyStack(){
           this.elem = new int[DEFAULT_CAPACITY];
     }
     //压栈,入栈
     public  void push(int val){
          if(isFull()){
               this.elem = Arrays.copyOf(elem,elem.length*2);
          }
          elem[usedSize++] = val;
     }

     public boolean isFull(){
          return  usedSize == elem.length;
     }
     //出栈
     public int pop(){
          if(isEmpty()){
               throw new StackEmptyException("栈为空");
          }
          int oldVal = elem[usedSize-1];
          usedSize--;
         // elem[usedSize] == null;
          return oldVal;
     }

     public boolean isEmpty(){
          return usedSize ==0;
     }

     public int peek(){
          if(isEmpty()){
               throw new StackEmptyException("栈为空");
          }
          return elem[usedSize-1];
     }


}

队列(Queue)

 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)。

入队列:进行插入操作的一端称为队尾

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

在java中,提供了Queue接口来实现队列。底层是通过链表实现的。

包括以下方法:

注:Queue是个接口,在实例化时必须实例化LinkedList的对象,因为LinkedList实现了Queue接口。

以下是队列的模拟实现;

package MyQueue;

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

        public ListNode(int val) {
            this.val = val;
        }
    }

    public ListNode head;
    public ListNode last;
    //入队
    public void offer(int val){
        ListNode node = new ListNode(val);
        if (head == null) {
            head = last = node;
        }else {
            //尾插
            last.next = node;
            node.prev = last;
            last = node;
        }
    }

    public int  poll(){
        if(head == null){
            return -1;
        }
         int val = -1; 
        if(head.next == null){
            val = head.val;
            head =null;
            last = null;
            return val;
        }
         val = head.val;
         head = head.next;
         head.prev = null;
         return val;
    }

    public boolean empty(){
        return head == null;
    }

    public int peek(){
        if(head == null){
            return -1;
        }
       return head.val;
    }
}

 循环队列

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

  如以下数组,我们可以定义rear和front指针,front表示队头rear表示队尾。队列采用头删尾插的方式。当插入元素时,rear向后++,当删除元素时,front也向后++。当rear来到队尾,超出数组下标时,就可以回到数组开头继续添加元素。数组就可以循环利用起来了。

问题:当rear和front相遇的时候,要么队列为空,要么队列为满。那么如何判断为空为满呢?

有以下方法:

1、添加usedSize属性来记录数组已经使用的长度。

2、牺牲一个空间,当rear的下一个元素时front的时候,此时rear指向的空间就不能再放了。

3、加标记,定义boolean类型的flag变量,初始为fasle,当rear与front第一次相遇的时候,置为true,当判断为true的时候,就说明再次相遇了。有可能是空,有可能是满。

注:rear如何从数组末尾回到数组开头:rear = (rear +1)%len

       rear如何获得它的前一个元素: elem[(rear + elem.length -1)%elem.length]

以下是循环队列的实现:

public class MyCircularQueue {
    public int[] elem;
    public int front;
    public int rear;

    public MyCircularQueue(int k){
        elem = new int[k];
    }

    //入队操作
    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];

    }
    //判空 front和rear相遇
    public boolean isEmpty(){
          return rear == front;
    }


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

练习一题:

给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。(力扣链接:. - 力扣(LeetCode))

解:

依次读取字符串,将字符放到栈中。如果是左括号,直接入栈。

如果是右括号: 有三种情况返回false:

1、在未读取完时,如果栈为空,返回false

2、读取到的右括号如果和左括号不匹配,返回false

3、在字符串读取完时,如果栈不为空,返回false

class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack  = new Stack();
        for(int i=0;i<s.length();i++){
            char ch = s.charAt(i);
            //是不是左括号
            if(ch == '(' || ch == '[' || ch == '{'){
                stack.push(ch);
            }else{
                //右括号
                //1.栈为空
                if(stack.isEmpty()){
                    return false;
                }
                //2.栈不为空
               char ch2 = stack.peek();
               if((ch == ')' && ch2 == '(' )||( ch == ']' && ch2 =='[') ||( ch == '}' && ch2 =='{')){
                  stack.pop();
               }else{
                return false;
               }
               
            }
        }
        return stack.isEmpty();
    }
}

以上,关于栈和队列,希望对你有所帮助。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024最新商业视频打赏系统源码 多套模板 有代理后台 已对接支付

简介&#xff1a; 2024最新商业视频打赏系统源码 多套模板 有代理后台 已对接支付 图片&#xff1a; 源码下载

IC-Light-在stable diffusion中实现图像的光影控制新方法 - 技术原理篇

&#x1f468;背景与来源 最近在stable diffusion的粉丝群看到光影控制又有了新的玩法&#xff0c;是controlnet的作者lllyasviel&#xff0c;发了一款名为IC-Light的模型&#xff0c;并且已经被另外一位名为huchenlei的朋友实现了comfyui和webUI&#xff08;forge &#xff0…

事件高级部分

一&#xff0c;注册事件 即给元素添加事件 1.传统注册方式 2.方法监听注册方式 事件类型&#xff1a;字符串形式&#xff0c;不用带on 可以给一个元素添加多个程序 二.删除事件 1.方式 参数见上文 三.DOM事件流 事件的传播过程叫做事件流 js代码只能获取一个阶段&#xf…

【考研数学】汤家凤“免单“数学题被吐槽‘太难’,老汤回应「怎么还有脸笑」,网友:这些题有毒!

我看了汤家凤老师出的几道题&#xff0c;实际上对于考研的同学来说&#xff0c;确实是送分题 第一个是三角函数变换中的万能公式&#xff1b;第二个e^x的泰勒展开公式&#xff1b;第三个是第一类重要极限。只要复习过&#xff0c;那基本上都能正常做出来。 至于汤家凤老师说「…

STM32快速入门(总线协议之I2C一主多从(软件实现 硬件实现))

STM32快速入门&#xff08;总线协议之I2C一主多从&#xff08;软件实现 & 硬件实现&#xff09;&#xff09; 前言 支持一对多&#xff08;一主多从&#xff09;、多对多传输&#xff08;多主多从&#xff09;&#xff0c;只支持半双工&#xff0c;一般有两根数据线&…

C++笔记(体系结构与内核分析)

1.OOP面向对象编程 vs. GP泛型编程 OOP将data和method放在一起&#xff0c;目的是通过封装、继承、多态提高软件的可维护性和可扩展性GP将data和method分开&#xff0c;可以将任何容器与任何算法结合使用&#xff0c;只要容器满足塞饭所需的迭代器类型 2.算法与仿函数的区别 …

OGG几何内核-网格化的改进

OGG社区于4月19日发布了OGG 1.0 preview版本。相对于OCCT 7.7.0有很多改进&#xff0c;目前在持续研究中。最近测试了一下网格化&#xff0c;确实有很好的改进。对比展示如下&#xff1a; 几何内核&#xff1a; OGG 1.0 preview 几何内核&#xff1a;OCCT 7.7.0 采用OCCT几何内…

IT项目管理-小题计算【太原理工大学】

1.合同总价问题 问承包商的利润是&#xff1f; 实际利润目标利润&#xff08;目标成本-实际成本&#xff09;*卖方分担比例 解&#xff1a;10 000&#xff08;100 000 - 90 000&#xff09;* 0.2 12 000&#xff08;元&#xff09; 实际成本有时也写作最终成本&#xff0c;问承…

cmu15445 2023fall project3 详细过程(下)QUERY EXECUTION

QUERY EXECUTION task3/task4 Task #3 - HashJoin Executor and Optimization1、HashJoin1.1 思路1.2 代码 2 NestedLoopJoin优化为HashJoin2.1 思路2.2 代码 Task #4 Sort Limit Executors Top-N Optimization Window Functions1、Sort1.1 思路1.2 代码 2、Limit Executors2…

Linux与Windows互传文件【笔记】

Linux与Windows互传文件【笔记】 前言前言推荐Linux与Windows互传文件首先确保Windows安装ssh如何传送文件问题 最后 前言 这是陈旧已久的草稿2023-05-10 00:01:24 这个是准备把计组课程华为智能计组的&#xff0c;传输文件。 最后发现&#xff0c;好像没有实现了。 现在202…

Java 守护线程 ( Daemon Thread )详解

在Java中&#xff0c;线程分为两类&#xff1a;用户线程(User Thread)和守护线程(Daemon Thread)。守护线程是后台线程&#xff0c;主要服务于用户线程&#xff0c;当所有的用户线程结束时&#xff0c;守护线程也会自动结束&#xff0c;JVM会随之退出。守护线程的一个典型例子是…

pikachu靶场(xss通关教程)

&#xff08;注&#xff1a;若复制注入代码攻击无效&#xff0c;请手动输入注入语句&#xff0c;在英文输入法下&#xff09; 反射型xss(get型) 1.打开网站 发现有个框&#xff0c;然后我们在框中输入一个“1”进行测试&#xff0c; 可以看到提交的数据在url处有显示&#xf…

AI跟踪报道第41期-新加坡内哥谈技术-本周AI新闻:本周Al新闻: 准备好了吗?事情即将変得瘋狂

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Oracle 删除表中的列

Oracle 删除表中的列 CONN SCOTT/TIGER DROP TABLE T1; create table t1 as select * from emp; insert into t1 select * from t1; / / --到6000行&#xff0c;构造一个实验用大表T1。 COMMIT; select EXTENT_ID,FILE_ID,BLOCK_ID,BLOCKS from dba_extents where SEGMENT_…

【Qt 学习笔记】Qt常用控件 | 布局管理器 | 水平布局Horizontal Layout

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 布局管理器 | 水平布局Horizontal Layout 文章编号&…

异常处理/CC++ 中 assert 断言 应用实践和注意事项

文章目录 概述assert 本质浅析Release版本下的assert是否生效默认设置下 QtCreator环境 assert 过程默认配置下 VS环境 assert 过程配置VS发布模式下的断言生效VS环境Release版本的UI程序Release下请当我不生效 请勿滥用assert导致逻辑错误再强调不要在assert内执行逻辑功能怎敢…

react18【系列实用教程】useContext —— Context 机制实现越层组件传值 (2024最新版)

什么是 Context 机制&#xff1f; Context 机制是 react 实现外层组件向内层组件传值的一种方案&#xff0c;父组件可以向其内部的任一组件传值&#xff0c;无论是子组件还是孙组件或更深层次的组件。 实现步骤 1.使用createContext方法创建一个上下文对象 Ctx 2.在顶层组件中通…

轮转数组 与 消失的数字

轮转数组 思路一 创建一个新内存空间&#xff0c;将需轮转的数依次放入&#xff0c;之后在把其它数放入 代码&#xff1a; void rotate(int* nums, int numsSize, int k) {k k % numsSize;// 确定有效的旋转次数if(k 0)return;int* newnums (int*)malloc(sizeof(int) * nu…

An 2024下载

An2024下载&#xff1a; 百度网盘下载https://pan.baidu.com/s/1cQQCFL16OUY1G6uQWgDbSg?pwdSIMS Adobe Animate 2024&#xff0c;作为Flash技术的进化顶点&#xff0c;是Adobe匠心打造的动画与交互内容创作的旗舰软件。这款工具赋予设计师与开发者前所未有的创意自由&#x…

设计模式-结构型-桥接模式-Bridge

桥接模式可以减少类的创建 矩阵类 public class Matrix {private String fileName;public Matrix(String fileName) {this.fileName fileName;}public String getFileName() {return fileName;} } 图片抽象类 public abstract class Image {protected ImageImp imp;public …