Java_栈_队列

文章目录

  • 一、栈(Stack)
    • 1.概念
    • 2.栈的使用
    • 3.栈的模拟实现
      • 1、定义接口
      • 2、定义栈
      • 3、成员
      • 4、构造方法
      • 5、判断空间是否满 full
      • 6、入栈 push
      • 7、出栈 pop
      • 8、获取栈顶元素 peek
      • 9、获取栈中有效元素个数 size
      • 10、检测栈是否为空 empty
      • 完整代码
    • 4.练习
      • 1、有效括号
      • 2、逆波兰表达式求值
      • 3、栈的压入,弹出序列
      • 4、最小栈
    • 5. 概念区分
  • 二、队列
    • 1.概念
    • 2.队列的使用
    • 3.模拟实现
      • 1、成员
      • 2、入队列 offer
      • 3、出队列 poll
      • 4、获取队头元素 peek
      • 5、获取队列中有效元素个数 size
      • 6、检查队列是否为空 isEmpty
      • 完整代码
  • 三、其他队列
    • 1.循环队列
      • 设计循环队列
    • 2.双端队列
    • 3.练习


一、栈(Stack)

1.概念

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

2.栈的使用

方法功能
Stack()构造一个空的栈
E push(E e)将e入栈
E pop()将栈顶元素出栈
E peek()获取栈顶元素
int size()获取栈中有效元素个数
boolean empty()检查栈是否为空
    public static void main(String[] args) {Stack<Integer> s =new Stack<>();s.push(1);s.push(2);s.push(3);s.push(4);System.out.println(s.size());System.out.println(s.peek());s.pop();System.out.println(s.pop());if(s.empty()){System.out.println("栈空");}else{System.out.println(s.size());}}

在这里插入图片描述

3.栈的模拟实现

在这里插入图片描述
从上图中可以看到,Stack继承了Vector,Vector和ArrayList类似,都是动态的顺序表,不同的是Vector是线程安全的。

1、定义接口

public interface IStack {void push(int x);int pop();int peek();int size();boolean empty();//判断是否满boolean full();
}

2、定义栈

public class MyStack implements IStack{@Overridepublic void push(int x) {}@Overridepublic int pop() {return 0;}@Overridepublic int peek() {return 0;}@Overridepublic int size() {return 0;}@Overridepublic boolean empty() {return false;}@Overridepublic boolean full() {return false;}
}

3、成员

存储数据的数组:

    private  int usedSize;

有效数据的个数:

    private  int usedSize;

默认大小:

    private  static  final  int DEFAULT_CAPACITY = 10;

4、构造方法

    public MyStack(){elem =new int[DEFAULT_CAPACITY];}

5、判断空间是否满 full

	@Overridepublic boolean full() {if(usedSize ==elem.length){return  true;}return false;}

6、入栈 push

    @Overridepublic void push(int x) {if(full()){elem = Arrays.copyOf(elem,elem.length*2);}elem[usedSize++] =x;}

7、出栈 pop

public class EmptyException extends RuntimeException{public EmptyException(String msg){super(msg);}}
-------------------------------------@Overridepublic int pop() {if(empty()){//抛异常throw new EmptyException("栈空,出栈异常");}int old = elem[usedSize--];//如果是引用就需要置空return old;}

8、获取栈顶元素 peek

    @Overridepublic int peek() {if(empty()){//抛异常throw new EmptyException("栈空");}return elem[usedSize-1];}

9、获取栈中有效元素个数 size

   @Overridepublic int size() {return usedSize;}

10、检测栈是否为空 empty

    @Overridepublic boolean empty() {return  usedSize==0;}

完整代码

public class EmptyException extends RuntimeException{public EmptyException(String msg){super(msg);}}----------------------------
public interface IStack {void push(int x);int pop();int peek();int size();boolean empty();//判断是否满boolean full();
}----------------------------------
import java.util.Arrays;public class MyStack  implements IStack{private  int [] elem;private  int usedSize;private  static  final  int DEFAULT_CAPACITY = 10;public MyStack(){elem =new int[DEFAULT_CAPACITY];}@Overridepublic boolean full() {if(usedSize ==elem.length){return  true;}return false;}@Overridepublic void push(int x) {if(full()){elem = Arrays.copyOf(elem,elem.length*2);}elem[usedSize++] =x;}@Overridepublic int pop() {if(empty()){//抛异常throw new EmptyException("栈空,出栈异常");}int old = elem[usedSize--];return old;}@Overridepublic int peek() {if(empty()){//抛异常throw new EmptyException("栈空");}return elem[usedSize-1];}@Overridepublic int size() {return usedSize;}@Overridepublic boolean empty() {return  usedSize==0;}
}

4.练习

1、有效括号

有效括号
开一个栈,遇到左括号进栈,遇到右括号检查栈顶和遇到右括号是否匹配。

class Solution {public boolean isValid(String s) {Stack<Character> st = new Stack<>();for(int i = 0;i<s.length();i++){char c =s.charAt(i);if(c=='('||c=='{'||c=='['){st.push(c);}else{if(c==')'&&!st.empty()){if(st.peek()!='('){return false;}st.pop();}else if(c=='}'&&!st.empty()){if(st.peek()!='{'){return false;}st.pop();}else if(c==']'&&!st.empty()){if(st.peek()!='['){return false;}st.pop();}else {return false;}}}if(st.empty()){return true;}return  false;}
}

2、逆波兰表达式求值

逆波兰表达式
判断是操作数还是算符,如果是操作数转Int存在栈,不是就按算符进行运算。

class Solution {boolean isOperation(String s){if(s.equals("+")||s.equals("-")||s.equals("*")||s.equals("/")){return  true;}return false;}public int evalRPN(String[] tokens) {Stack<Integer > st = new Stack<>();for(int i = 0;i<tokens.length;i++){String s  =  tokens[i];if(isOperation(s)){int right  = 0;int left=0 ;if(st.size()>=2){right = st.pop();left = st.pop();}if(s.equals("+")){st.push(left+right);}else if(s.equals("-")){st.push(left-right);}else if(s.equals("*")){st.push(left*right);}else if(s.equals("/")){st.push(left/right);}}else{int temp = Integer.parseInt(s);st.push(temp);}}return st.peek();}
}

3、栈的压入,弹出序列

栈的压入,弹出序列
先创建一个栈模拟压入,循环检查是否可以出栈,如果符合就出栈,不符合继续压入,直到全部压入但不能出栈,即为不符合弹出序列。

import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param pushV int整型一维数组* @param popV int整型一维数组* @return bool布尔型*/public boolean IsPopOrder (int[] pushV, int[] popV) {Stack<Integer> st = new Stack<>();int cur1= 0;int cur2 =0;int len = pushV.length;while(cur1<len||cur2<len){if(cur1<len){st.push(pushV[cur1]);}while(cur2<len){if(!st.empty()&&st.peek()==popV[cur2]){st.pop();cur2++;}else {if(cur1<len){break;}else{return false;}}}cur1++;}return st.empty();}
}

4、最小栈

最小栈
开两个栈,一个存最小值的栈,一个就是普通的栈。在入栈的时候,判断存最小值的栈是否为空,空就同时入这两个栈,不为空就要比较存最小值的栈上面的值和新入的值,如果比最小栈的值还小或等于就同时入两栈,否则只入普通栈。

class MinStack {private  Stack<Integer> stack;private  Stack<Integer> minStack;public MinStack() {stack =new Stack<>();minStack = new Stack<>();}public void push(int val) {stack.push(val);if(minStack.empty()){minStack.push(val);}else{if(minStack.peek()>=val){minStack.push(val);}}}public void pop() {if(minStack.peek().equals(stack.peek())){minStack.pop();}stack.pop();}public int top() {return  stack.peek();}public int getMin() {return minStack.peek();}
}

5. 概念区分

栈、虚拟机栈、栈帧有什么区别?
栈:数据结构
虚拟机栈:JVM划分的一款内存而已
栈帧:调用方法的时候会在虚拟机当中给这个方法开辟一块内存

二、队列

1.概念

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

2.队列的使用

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

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

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

    public static void main(String[] args) {Queue<Integer> queue = new LinkedList<>();queue.offer(1);queue.offer(2);queue.offer(3);System.out.println(queue.size());System.out.println(queue.peek());queue.poll();System.out.println(queue.isEmpty());System.out.println(queue.poll());System.out.println(queue.poll());System.out.println(queue.isEmpty());}

在这里插入图片描述

3.模拟实现

1、成员

双向链表节点

    static class ListNode{public int val;public ListNode next;public ListNode prev;public ListNode(int val){this.val =val;}}

头尾引用

    public ListNode head;public ListNode last;

节点个数

    public int size;

2、入队列 offer

   boolean offer(int val){ListNode node = new ListNode(val);if(head==null){head = node;last = node;}else{last.next = node;node.prev = last;last = node;}size++;return true;}

3、出队列 poll

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

4、获取队头元素 peek

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

5、获取队列中有效元素个数 size

   public  int size(){return  size;}

6、检查队列是否为空 isEmpty

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

完整代码

package queuedemo;import java.util.List;public class MyLinkQueue  {static class ListNode{public int val;public ListNode next;public ListNode prev;public ListNode(int val){this.val =val;}}public ListNode head;public ListNode last;public int size;boolean offer(int val){ListNode node = new ListNode(val);if(head==null){head = node;last = node;}else{last.next = node;node.prev = last;last = node;}size++;return true;}public  int poll(){if(head==null){return -1;}size--;int ret  = head.val;if(head.next==null){head =null;last  = null;return ret;}head.next.prev = null;head = head.next;return ret;}public int peek(){if(head==null){return -1;}return head.val;}public  int size(){return  size;}public  boolean isEmpty(){return size==0;}}

三、其他队列

1.循环队列

实际中我们有时还会使用一种队列叫循环队列。如操作系统课程讲解生产者消费者模型时可以就会使用循环队列。环形队列通常使用数组实现。
在这里插入图片描述
问题:


如何判断是空还是满?
解决空还是满有很多种方案:
1.使用usedSize进行记录
2.浪费一个空间来表示满
3.使用标记


如何从7下标来到0下标?
(队尾指针+1)%len

设计循环队列

设计循环队列


class MyCircularQueue {public int [] elem;int front = 0;int rear  = 0;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 temp = (rear-1+elem.length)%elem.length;return  elem[temp];}public boolean isEmpty() {return  front==rear;}public boolean isFull() {return  (rear+1)%elem.length==front;}
}

2.双端队列

双端队列(deque)是指允许两端都可以进行入队和出队操作的队列,deque 是 “double ended queue” 的简称。那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。
Deque是一个接口,使用时必须创建LinkedList的对象。

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

3.练习

队列实现栈

class MyStack {Queue<Integer> que1;Queue<Integer> que2;public MyStack() {que1 = new LinkedList<>();que2 = new LinkedList<>();}public void push(int x) {if(que1.isEmpty()&&que2.isEmpty()){que1.offer(x);}else{if(que1.isEmpty()){que2.offer(x);}else{que1.offer(x);}}}public int pop() {int size ;if(que1.isEmpty()){size = que2.size();for(int i = 0;i<size-1;i++){que1.offer(que2.poll());}return que2.poll();}else{size = que1.size();for(int i = 0;i<size-1;i++){que2.offer(que1.poll());}return que1.poll();}}public int top() {if(que1.isEmpty()){int size = que2.size();for(int i = 0;i<size-1;i++){que1.offer(que2.poll());}int ret =que2.poll();que1.offer(ret);return ret;}else{int size = que1.size();for(int i = 0;i<size-1;i++){que2.offer(que1.poll());}int ret =que1.poll();que2.offer(ret);return ret;}}public boolean empty() {return  que2.isEmpty()&&que1.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() {if(stack2.isEmpty()){while(!stack1.isEmpty()){stack2.push(stack1.pop());}}return  stack2.peek();}public boolean empty() {return stack2.isEmpty()&&stack1.isEmpty();}
}

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

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

相关文章

免费搭建幻兽帕鲁服务器,白嫖阿里云游戏服务器

阿里云幻兽帕鲁服务器免费搭建方案&#xff0c;先在阿里云高校计划「云工开物」活动领取学生专享300元无门槛代金券&#xff0c;幻兽帕鲁专用服务器4核16G配置26元1个月、149元半年&#xff0c;直接使用这个无门槛300元代金券抵扣即可免费搭建幻兽帕鲁服务器。阿里云服务器网al…

除夕快乐(前端小烟花)

家人们&#xff0c;新的一年好运常在&#xff0c;愿大家在新的一年里得偿所愿&#xff0c;发财暴富&#xff0c;愿大家找到属于自己的那个公主&#xff0c;下面就给大家展示一下给公主的烟花 前端烟花 新的一年&#xff0c;新的挑战&#xff0c;愿我们不忘初心&#xff0c;砥砺…

C++ 动态规划 树形DP 没有上司的舞会

Ural 大学有 N 名职员&#xff0c;编号为 1∼N 。 他们的关系就像一棵以校长为根的树&#xff0c;父节点就是子节点的直接上司。 每个职员有一个快乐指数&#xff0c;用整数 Hi 给出&#xff0c;其中 1≤i≤N 。 现在要召开一场周年庆宴会&#xff0c;不过&#xff0c;没有职…

口袋工具箱微信小程序源码

这是一款云开发口袋工具箱微信小程序源码&#xff0c;只有纯前端版本&#xff0c;该版本的口袋工具箱涵盖了13个功能&#xff0c;分别为圣诞帽头像生成、二维码生成、日语50音图、汉字拼音查询、计算器、程序员黄历、娱乐摇骰子、身材计算、所在地天气查询、IP地址查询、手机归…

自制微信红包封面

一.前言 这不是过年了吗&#xff0c;各大平台都发放了免费的微信红包封面&#xff0c;但我老是抢不到QAQ。于是乎&#xff0c;我便想“授人以鱼不如授人以渔”&#xff0c;不如自己造个封面。 二.主要步骤 1.条件 1>创建视频号 2>过去一年发表过视频号 3>过去一…

【JavaScript 漫游】【012】ES5 规范中 String 对象方法汇总

文章简介 本文为【JavaScript 漫游】专栏的第 012 篇文章&#xff0c;记录的内容包含了 ES5 规范中String 对象的所有方法。 笔者认为要掌握的方法包括&#xff1a; String.prototype.concat()String.prototype.slice()String.prototype.substring()String.prototype.substr…

MacOS上怎么把格式化成APFS的U盘或者硬盘格式化回ExFAT?

一、问题 MacOS在更新MacOS Monterey后或者更高系统后发现&#xff0c;格式U盘或者硬盘只有4个APFS选项&#xff0c;那么我们该如何将APFS格式成ExFAT&#xff1f; 二、解答 将APFS的U盘或者硬盘拓展成MacOS的拓展格式即可&#xff0c;操作步骤如下 1、电脑接入U盘或者硬盘 2…

vue3 之 商城项目—二级分类

二级分类功能描述 配置二级路由 准备组件模版 <script setup></script><template><div class"container "><!-- 面包屑 --><div class"bread-container"><el-breadcrumb separator">"><el-bre…

GPT如何在一分钟内完成论文数据分析?

数据上传 PPMAN-AI 01 由于技术限制&#xff0c;目前InfinitePaper AI仅支持上传1份文件&#xff0c;且大小不超过10M。但是&#xff0c;在强大的代码解释器面前&#xff0c;这都是小问题。我们只需要将可能用到的文件打包成压缩文件上传即可&#xff0c;之后要求GPT直接解压…

Spring基础 - Spring核心之控制反转(IOC)

Spring基础 - Spring核心之控制反转(IOC) 引入 Spring框架管理这些Bean的创建工作&#xff0c;用户管理Bean转变为框架管理Bean&#xff0c;这个称之为控制翻转Spring框架托管创建的Bean放在IOC容器中Spring框架为了更好让用户配置Bean&#xff0c;必然会引入不同方式来配置B…

网络协议、网络传输认识

目录 网络协议概念 网络协议具象化理解 协议分层 TCP/IP模型 网络传输基本流程 网络协议概念 网络协议是计算机网络中用于在通信设备之间传输数据的规则集合。这些规则定义了数据的格式、传输方式、错误检测和纠正方法等&#xff0c;以确保不同设备之间的通信能够正确进行…

Amazon Dynamo学习总结

目录 一、Amazon Dynamo的问世 二、Amazon Dynamo主要技术概要 三、数据划分算法 四、数据复制 五、版本控制 六、故障处理 七、成员和故障检测 一、Amazon Dynamo的问世 Amazon Dynamo是由亚马逊在2007年开发的一种高度可扩展和分布式的键值存储系统&#xff0c;旨在解…

百度Apollo荣获量子位-智能车参考“2023智能车年度评选”两大奖项

2023&#xff0c;是谁在引领智能车浪潮&#xff1f; 量子位-智能车参考发布“2023智能车年度评选”结果。经过业内专业评审和垂直社群万人票选后&#xff0c;百度Apollo荣获「年度十大智能车技术产品/方案」「年度十大智能车领军人物」两项大奖。 年度十大智能车技术产品\方…

jvm问题自查思路

本文聊一下最近处理了一些jvm的问题上&#xff0c;将这个排查和学习过程分享一下&#xff0c;看了很多资料&#xff0c;最终都会落地到几个工具的使用&#xff0c;本文主要是从文档学习、工具学习和第三方技术验证来打开认知和实践&#xff0c;希望有用。 一、文档 不仅知道了…

springboot+vue居民小区设备报修系统

小区报修系统可以提高设施维护的效率&#xff0c;减少机构的人力物力成本&#xff0c;并使得维修人员可以更好地了解维护设备的情况&#xff0c;及时解决问题。 对于用户来说&#xff0c;报修系统也方便用户的维修请求和沟通&#xff0c;提高了用户的满意度和信任。其次小区报修…

imazing是啥?imazing有什么用

iMazing 是一款用于管理 iOS 设备的第三方软件。它支持在 Windows 或 Mac 电脑上对连接的 iPhone、iPad 或 iPod 进行数据传输、备份和管理工作。用户可以通过 iMazing 传输和备份包括照片、音乐、铃声、视频、电子书和通讯录等在内的多种信息。iMazing 的功能与苹果官方的 iTu…

函数及函数的定义

前言&#xff1a; 在之前介绍指针的时候&#xff0c;小编发现有些地方需要用函数&#xff0c;所以小编决定先带领大家学习函数&#xff0c;然后再学习指针。 函数是从英文function翻译过来的&#xff0c;其实function在英文中的意思就是函数&#xff0c;也是功能的意思&#xf…

UE4运用C++和框架开发坦克大战教程笔记(十九)(第58~60集)完结

UE4运用C和框架开发坦克大战教程笔记&#xff08;十九&#xff09;&#xff08;第58~60集&#xff09;完结 58. 弹窗显示与隐藏59. UI 面板销毁60. 框架完成与总结 58. 弹窗显示与隐藏 这节课我们先来补全 TransferMask() 里对于 Overlay 布局类型面板的遮罩转移逻辑&#xff…

C++,stl,栈stack和队列queue详解

1.栈stack 1.stack基本概念 2.stack常用接口 代码示例&#xff1a; #include<bits/stdc.h> using namespace std;int main() {stack<int> stk;stk.push(7);stk.push(9);stk.push(5);cout << "栈的size为&#xff1a;" << stk.size() <…

【STL】list模拟实现

vector模拟实现 一、接口大框架函数声明速览二、结点类的模拟实现1、构造函数 三、迭代器类的模拟实现1、迭代器类存在的意义2、迭代器类的模板参数说明3、构造函数4、运算符的重载&#xff08;前置和后置&#xff09;&#xff08;1&#xff09;前置&#xff08;2&#xff09;后…