数据结构《栈和队列》

文章目录

  • 一、什么是栈?
    • 1.1 栈的模拟实现
    • 1.2 关于栈的例题
  • 二、什么是队列?
    • 2.2 队列的模拟实现
    • 2.2 关于队列的例题
  • 总结


提示:关于栈和队列的实现其实很简单,基本上是对之前的顺序表和链表的一种应用,代码部分也不难。主要的是对栈和队列的实际运用。

一、什么是栈?

可以理解为一个竖过来的数组、顺序表,同时这个数组只能将末尾的元素先推出来,再推出来前面的元素,也就是我们所说的,先进后出、后进先出。
在这里插入图片描述
栈的实例化

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

1.1 栈的模拟实现

在这里插入图片描述


自定义的接口,规范自定义的类,便于模拟实现

public interface IStack {//放入元素int push(int a);//推出栈顶元素int pop();//查看栈顶元素int peek();//栈是否为空boolean isEmpty(int[] array);//栈中的元素个数int size();//栈中寻找某个元素距离栈顶的距离int search(int a);
}

push(int a) — 将元素放入栈中

public int push(int a) {isFull(array);array[useSide++] = a;return a;}

在这里插入图片描述


peek() — 查看栈顶元素

public int peek() {try {if(isEmpty(array)){throw new EmptyException("空数组读取异常");}}catch (EmptyException e){e.printStackTrace();}return array[useSide - 1];}

在这里插入图片描述


pop() — 出栈顶元素

public int pop() {int top = peek();useSide--;return top;}

在这里插入图片描述


isEmpty(int[] array) — 判断栈是否为空

public boolean isEmpty(int[] array) {return array.length == useSide;}

size() — 得到栈中的元素个数

public int size() {return useSide;}

search(int a) — 得到栈中某个元素距离栈顶的距离,栈顶元素位置按1来计算

public int search(int a) {int cur = useSide - 1;int len = 1;while (0 <= cur){if(a == array[cur]){return len;}else {cur--;len++;}}return -1;}

代码整合

public class MyStack implements IStack{private int[] array;public MyStack() {this.array = new int[10];}private int useSide;private void isFull(int[] check){if(isEmpty(check)){array = Arrays.copyOf(check,2*check.length);}}@Overridepublic int push(int a) {isFull(array);array[useSide++] = a;return a;}@Overridepublic int pop() {int top = peek();useSide--;return top;}@Overridepublic int peek() {try {if(isEmpty(array)){throw new EmptyException("空数组读取异常");}}catch (EmptyException e){e.printStackTrace();}return array[useSide - 1];}@Overridepublic boolean isEmpty(int[] array) {return array.length == useSide;}@Overridepublic int size() {return useSide;}@Overridepublic int search(int a) {int cur = useSide - 1;int len = 1;while (0 <= cur){if(a == array[cur]){return len;}else {cur--;len++;}}return -1;}
}

1.2 关于栈的例题

例题1 有效括号
在这里插入图片描述
在这里插入图片描述

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

例题2 逆波兰表达式
在这里插入图片描述

public int evalRPN(String[] tokens) {Stack<String> stack = new Stack<>();for(int i = 0; i < tokens.length; i++){if(tokens[i].equals("+") || tokens[i].equals("-") || tokens[i].equals("*") || tokens[i].equals("/")){int m = Integer.parseInt(stack.pop());int n = Integer.parseInt(stack.pop());if(tokens[i].equals("+")){stack.push(String.valueOf(m+n));}else if(tokens[i].equals("-")){stack.push(String.valueOf(n-m));}else if(tokens[i].equals("*")){stack.push(String.valueOf(m*n));}else{stack.push(String.valueOf(n/m));}}else{stack.push(tokens[i]);}}return Integer.parseInt(stack.pop());}

例题3 最小栈
在这里插入图片描述

public Stack<Integer> stack;public 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{int m = minStack.peek();if(m >= val){minStack.push(val);}}}public void pop() {if(stack.empty()){return;}int m = stack.pop();if(m == minStack.peek()){minStack.pop();}}public int top() {if(stack.empty()){return -1;}return stack.peek();}public int getMin() {if(minStack.empty()){return -1;}return minStack.peek();}

例题4 栈的压入、弹出序列
在这里插入图片描述

public boolean IsPopOrder (int[] pushV, int[] popV) {// write code hereStack<Integer> stack = new Stack<>();int j = 0;for(int i = 0; i < pushV.length;i++){stack.push(pushV[i]);while(!stack.isEmpty() && stack.peek() == popV[j] && j < popV.length){stack.pop();j++;}}return stack.isEmpty();}

二、什么是队列?

可以理解为一个双向链表(一个一个节点在排队),同时这个链表只能将队头的元素先推出来,再推出来后面的元素,也就是我们所说的,先进先出、后进后出。
在这里插入图片描述
队列的实例化

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

2.2 队列的模拟实现

在这里插入图片描述


自定义的接口,规范自定义的类,便于模拟实现

public interface IQueue {//int offer(int a);int poll();int peek();boolean isEmpty();
}

isEmpty() — 判断是否为空队列

@Overridepublic boolean isEmpty() {return useSide == 0;}

offer(int a) — 从队尾放入元素

public int offer(int a) {ListNode listNode = new ListNode(a);listNode.val = a;if(isEmpty()){head = listNode;last = listNode;}else {last.next = listNode;listNode.pre = last;last = listNode;}useSide++;return a;}

在这里插入图片描述


peek() — 查看队头元素

public int peek() {try {if(head == null){throw new EmptyException("空指针异常访问");}}catch (EmptyException e){e.printStackTrace();}return head.val;}

在这里插入图片描述


poll() — 推出队头的元素

public int poll() {int fisrt = peek();head = head.next;useSide --;return fisrt;}

在这里插入图片描述


代码整合

public class MyQueue implements IQueue{static class ListNode{int val;ListNode pre;ListNode next;public ListNode(int val) {this.val = val;}}private ListNode head;private ListNode last;private int useSide;@Overridepublic int offer(int a) {ListNode listNode = new ListNode(a);listNode.val = a;if(isEmpty()){head = listNode;last = listNode;}else {last.next = listNode;listNode.pre = last;last = listNode;}useSide++;return a;}@Overridepublic int poll() {int fisrt = peek();head = head.next;useSide --;return fisrt;}@Overridepublic int peek() {try {if(head == null){throw new EmptyException("空指针异常访问");}}catch (EmptyException e){e.printStackTrace();}return head.val;}@Overridepublic boolean isEmpty() {return useSide == 0;}}

2.2 关于队列的例题

例题1 设计循环队列
在这里插入图片描述

class MyCircularQueue {public int[] array;int front;int rear;public MyCircularQueue(int k) {array = new int[k+1];}// 向循环队列插入一个元素。如果成功插入则返回真。public boolean enQueue(int value) {if(isFull()){return false;}array[rear] = value;rear = (rear+1) % array.length;return true;}//从循环队列中删除一个元素。如果成功删除则返回真。public boolean deQueue() {if(isEmpty()){return false;}front = (front+1) % array.length;return true;}//从队首获取元素。如果队列为空,返回 -1 。public int Front() {if(isEmpty()){return -1;}return array[front];}//获取队尾元素。如果队列为空,返回 -1 。public int Rear() {if(isEmpty()){return -1;}if(rear == 0){return array[array.length - 1];}return array[rear-1];}//检查循环队列是否为空。public boolean isEmpty() {return rear == front;}//检查循环队列是否已满。public boolean isFull() {return (rear+1) % array.length == front;}
}

例题2 用队列实现栈
在这里插入图片描述

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

例题3 用栈实现队列
在这里插入图片描述

Stack<Integer> stack1;Stack<Integer> stack2;int size = 0;public MyQueue() {stack1 = new Stack<>();stack2 = new Stack<>();}//将元素 x 推到队列的末尾public void push(int x) {stack1.push(x);size++;}//从队列的开头移除并返回元素public int pop() {if(empty()){return -1;}if(!stack2.isEmpty()){size--;return stack2.pop();}else if(stack2.isEmpty() && !stack1.isEmpty()){while(!stack1.isEmpty()){stack2.push(stack1.pop());}size--;return stack2.pop();}return -1;}//返回队列开头的元素public int peek() {if(empty()){return -1;}if(!stack2.isEmpty()){return stack2.peek();}else if(stack2.isEmpty() && !stack1.isEmpty()){while(!stack1.isEmpty()){stack2.push(stack1.pop());}return stack2.peek();}return -1;}//如果队列为空,返回 true ;否则,返回 falsepublic boolean empty() {return size == 0;}

总结

本篇文章介绍了有关数据结构中的栈和队列的相关内容,以及它们的简单实现,和简单使用,如果有什么不正确的或者不严谨的地方,还望指正,谢谢大家!

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

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

相关文章

基于BERT的命名体识别(NER)

基于BERT的命名实体识别&#xff08;NER&#xff09; 目录 项目背景项目结构环境准备数据准备代码实现 5.1 数据预处理 (src/preprocess.py)5.2 模型训练 (src/train.py)5.3 模型评估 (src/evaluate.py)5.4 模型推理 (src/inference.py) 项目运行 6.1 一键运行脚本 (run.sh)6…

从0-1训练自己的数据集实现火焰检测

随着工业、建筑、交通等领域的快速发展,火灾作为一种常见的灾难性事件,对生命财产安全造成了严重威胁。为了提高火灾的预警能力,减少火灾损失,火焰检测技术应运而生,成为火灾监控和预防的有效手段之一。 传统的火灾检测方法,如烟雾探测器、温度传感器等,存在响应时间慢…

WSL--无需安装虚拟机和docker可以直接在Windows操作系统上使用Linux操作系统

安装WSL命令 管理员打开PowerShell或Windows命令提示符&#xff0c;输入wsl --install&#xff0c;然后回车 注意&#xff1a;此命令将启用运行 WSL 和安装 Linux 的 Ubuntu 发行版所需的功能。 注意&#xff1a;默认安装最新的Ubuntu发行版。 注意&#xff1a;默认安装路径是…

minikube start --driver=docker 指定国内镜像

要在Ubuntu 22上使用Minikube并指定国内镜像&#xff0c;你可以根据以下步骤操作&#xff1a; 安装Minikube&#xff1a; 你可以通过阿里云提供的国内源来安装Minikube&#xff0c;这样可以避免访问国外源的问题。使用以下命令安装Minikube&#xff1a; curl -Lo minikube http…

【windows笔记】06-win11右键菜单默认显示更多选项(win10老菜单),解决反人类 恢复传统右键的方法

写在前面 win11的新菜单选项是为了提高右键菜单的相应速度&#xff0c;如果切换回win10的老菜单&#xff0c;会一定程度&#xff08;看条目数量&#xff09;降低右键响应速度 所以要不要切换先考虑清楚❤️ 部分人喜欢新的样式&#xff0c;毕竟比较漂亮&#xff0c;部分选项要…

云原生-docker安装与基础操作

一、云原生 Docker 介绍 Docker 在云原生中的优势 二、docker的安装 三、docker的基础命令 1. docker pull&#xff08;拉取镜像&#xff09; 2. docker images&#xff08;查看本地镜像&#xff09; 3. docker run&#xff08;创建并启动容器&#xff09; 4. docker ps…

@Autowired 和 @Resource思考(注入redisTemplate时发现一些奇怪的现象)

1. 前置知识 Configuration public class RedisConfig {Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template new RedisTemplate<>();template.setConnectionFactory(facto…

HarmonyOS ArkUI(基于ArkTS) 常用组件

一 Button 按钮 Button是按钮组件&#xff0c;通常用于响应用户的点击操作,可以加子组件 Button(我是button)Button(){Text(我是button)}type 按钮类型 Button有三种可选类型&#xff0c;分别为胶囊类型&#xff08;Capsule&#xff09;、圆形按钮&#xff08;Circle&#xf…

Jenkins + gitee 自动触发项目拉取部署(Webhook配置)

目录 前言 Generic Webhook Trigger 插件 下载插件 ​编辑 配置WebHook 生成tocken 总结 前言 前文简单介绍了Jenkins环境搭建&#xff0c;本文主要来介绍一下如何使用 WebHook 触发自动拉取构建项目&#xff1b; Generic Webhook Trigger 插件 实现代码推送后&#xff0c;触…

React Native 全栈开发实战班 - 网络与数据之网络请求基础

在移动应用中&#xff0c;网络请求 是实现与服务器进行数据交互的核心功能。React Native 基于 JavaScript 的特性&#xff0c;提供了多种方式进行网络请求&#xff0c;包括使用 fetch API、axios 库以及 WebSocket 等。本章节将详细介绍如何在 React Native 中进行网络请求&am…

【插件】重复执行 pytest-repeat

安装 pip3 install pytest-repeat 用法 1.命令行 pytest --count num pytest --count 32.装饰器 pytest.mark.repeat(num) #num运行次数 pytest.mark.repeat(5)#执行结果如下&#xff1a;

软件测试 —— 自动化基础

目录 前言 一、Web 自动化测试 1.什么是 Web 自动化测试 2.驱动 3.安装驱动管理 二、Selenium 1.简单 web 自动化测试示例 2.工作原理 三、元素定位 1.cssSelector 2.XPath 四、操作测试对象 1.点击/提交对象 2.模拟按键输入 3.清除文本内容 4.获取文本信息 5.…

Java中 LinkedList<>,ArrayDeque<>的区别 || Queue和Deque的区别

我是你爹 LinkedList<> 和 ArrayDeque<> 的区别Queue接口 和 Deque接口区别Queue 的用法Deque 的用法 LinkedList<> 和 ArrayDeque<> 的区别 1. 数据结构实现方式&#xff1a; LinkedList&#xff1a; 基于链表结构&#xff0c;是一个双向链表。每个…

HVV蓝队基础

免责声明 学习视频来自B 站up主泷羽sec&#xff0c;如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识&#xff0c;以下代码、网站只涉及学习内容&#xff0c;其他的都与本人无关&#xff0c;切莫逾越法律红线&#xff0c;否则后果自负。 企业网络架构 企业技术和信…

Docker+Django项目部署-从Linux+Windows实战

一、概述 1. 什么是Docker Docker 是一个开源的应用容器引擎&#xff0c;支持在win、mac、Linux系统上进行安装。可以帮助我们在一台电脑上创建出多个隔离的环境&#xff0c;比传统的虚拟机极大的节省资源 。 为什么要创建隔离的环境&#xff1f; 假设你先在有一个centos7.…

分布式,微服务,SpringCloudAlibaba,nacos,gateway,openFeign

想学习微服务SpringCloudAlibaba的小伙伴&#xff0c;可以观看视频 地址&#xff1a; https://www.bilibili.com/video/BV1cFDEYWEkY/?vd_source14d27ec13a4737c281b7c79463687112分布式架构和微服务是两个密切相关但又有所区别的概念。它们在现代软件工程中经常被提及&#…

【jvm】如何破坏双亲委派机制

目录 1.说明2.重写ClassLoader的loadClass方法2.1 原理2.2 实现步骤2.3 注意事项 3.使用线程上下文类加载器3.1 原理3.2 实现步骤3.3 应用场景 4.利用SPI机制4.1 原理4.2 实现步骤4.3 应用场景 5.Tomcat等容器的自定义类加载器5.1 原理5.2 实现方式5.3 应用场景 1.说明 1.双亲委…

深度学习工具和框架详细指南:PyTorch、TensorFlow、Keras

引言 在深度学习的世界中&#xff0c;PyTorch、TensorFlow和Keras是最受欢迎的工具和框架&#xff0c;它们为研究者和开发者提供了强大且易于使用的接口。在本文中&#xff0c;我们将深入探索这三个框架&#xff0c;涵盖如何用它们实现经典深度学习模型&#xff0c;并通过代码…

蓝桥杯-洛谷刷题-day3(C++)

目录 1.忽略回车的字符串输入 i.getline() ii.逐个字符的识别再输入 2.获取绝对值abs() 3.做题时的误区 4.多个变量的某一个到达判断条件 i.max() 5.[NOIP2016 提高组] 玩具谜题 i.代码 6.逻辑上的圆圈 i.有限个数n的数组 7.数组的定义 i.动态数组 1.忽略回车的字符串输…

fast-api后端 + fetch 前端流式文字响应

fast-api后端 fetch 前端流式文字响应 fast-api后台接口流式响应 前端fetch 流式文本数据处理 fast-api后台接口 流式响应 from fastapi.responses import StreamingResponse from tqdm import tqdm from pydantic import BaseModelclass ItemDataSingle(BaseModel):data: …