数据结构《栈和队列》
文章目录
- 一、什么是栈?
- 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;}
总结
本篇文章介绍了有关数据结构中的栈和队列的相关内容,以及它们的简单实现,和简单使用,如果有什么不正确的或者不严谨的地方,还望指正,谢谢大家!
相关文章:

数据结构《栈和队列》
文章目录 一、什么是栈?1.1 栈的模拟实现1.2 关于栈的例题 二、什么是队列?2.2 队列的模拟实现2.2 关于队列的例题 总结 提示:关于栈和队列的实现其实很简单,基本上是对之前的顺序表和链表的一种应用,代码部分也不难。…...

C# 超链接控件LinkLabel无法触发Alt快捷键
在C#中,为控件添加快捷键的方式有两种,其中一种就是Windows中较为常见的Alt快捷键,比如运行对话框,记事本菜单等。只需要按下 Alt 框号中带下划线的字母即可触发该控件的点击操作。如图所示 在C#开发中,实现类似的操作…...

JVM类加载过程-Loading
一、Class对象的生命周期 .class文件是如何加载到内存中:.class文件是ClassLoader通过IO将文件读到内存,再通过双亲委派的模式进行Loading,再Linking、以及Initializing,代码调用等一系列操作后,进行GC,组成完整的生命周期; 二、双亲委派模式(Loading的过程): 1、类…...
2024年11月19日Github流行趋势
项目名称:build-your-own-x 项目维护者:danistefanovic, rohitpaulk, sarupbanskota 等项目介绍:通过从零开始重新创建你最喜欢的技术来掌握编程。项目star数:312,081项目fork数:29,004 项目名称:freqtrad…...

详细描述一下Elasticsearch索引文档的过程?
大家好,我是锋哥。今天分享关于【详细描述一下Elasticsearch索引文档的过程?】面试题。希望对大家有帮助; 详细描述一下Elasticsearch索引文档的过程? Elasticsearch的索引文档过程是其核心功能之一,涉及将数据存储到…...

基于css的Grid布局和vue实现点击左移右移轮播过渡动画效果
直接上代码,以下代码基于vue2,需要Vue3或者react可以使用国内直连GPT/Claude来帮你转换下 代码如下: // ScrollCardsGrid.vue <template><div class"scroll-cards-container"><!-- 左箭头 --><div v-show"showLef…...

HarmonyOS NEXT应用元服务开发Intents Kit(意图框架服务)习惯推荐方案概述
一、习惯推荐是HarmonyOS学习用户的行为习惯后做出的主动预测推荐。 1.开发者将用户在应用/元服务内的使用行为向HarmonyOS共享,使得HarmonyOS可以基于共享的数据学习用户的行为习惯。 2.在HarmonyOS学习到用户的行为习惯后,会给用户推荐相应功能&#x…...
【AtCoder】Beginner Contest 380-F.Exchange Game
题目链接 Problem Statement Takahashi and Aoki will play a game using cards with numbers written on them. Initially, Takahashi has N N N cards with numbers A 1 , … , A N A_1, \ldots, A_N A1,…,AN in his hand, Aoki has M M M cards with numbers B …...

30. 并发编程
一、什么是多任务 如果一个操作系统上同时运行了多个程序,那么称这个操作系统就是 多任务的操作系统,例如:Windows、Mac、Android、IOS、Harmony 等。如果是一个程序,它可以同时执行多个事情,那么就称为 多任务的程序。…...

【包教包会】CocosCreator3.x框架——带翻页特效的场景切换
一、效果演示 二、如何获取 1、https://gitee.com/szrpf/TurnPage 2、解压,导入cocos creator(版本3.8.2),可以直接运行Demo演示 三、算法思路 1、单场景 页面预制体 通过loadScene来切换页面,无法实现页面特效。…...
k8s上面的Redis集群链接不上master的解决办法
问题描述 之前在k8s上面部署了一台node,然后创建了6个redis的pod,构建了一个redis的集群,正常运行。 最近添加了一台slave node,然后把其中的几个redis的pod调度到了slave node上面,结果集群就起不来了,…...

<项目代码>YOLOv8 瞳孔识别<目标检测>
YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如Faster R-CNN),YOLOv8具有更高的…...

网络编程-002-UDP通信
1.UDP通信的简单介绍 1.1不需要通信握手,无需维持连接,网络带宽需求较小,而实时性要求高 1.2 包大小有限制,不发大于路径MTU的数据包 1.3容易丢包 1.4 可以实现一对多,多对多 2.客户端与服务端=发送端与接收端 代码框架 收数据方一般都是客户端/接收端 3.头文件 #i…...

MySQL更换瀚高语法更换
MySQL更换瀚高语法更换 一、前言二、语句 一、前言 水一篇,mysql更换瀚高之后,一些需要更换的语法介绍 > 二、语句 MySQL瀚高MySQL用法瀚高用法说明ifnull(x,y)coalesce(x,y)相同相同用于检查两个表达式并返回第一个非空表达式。如果第一个表达式不是 NULL&…...
Object.prototype.hasOwnProperty.call(item, key) 作用与用途
在 JavaScript 中,Object.prototype.hasOwnProperty.call(item, key) 是一种检查对象 item 是否具有特定属性 key 作为自身的属性(而不是继承自原型链)的方法。这种调用方式是安全的,特别是在处理可能被修改过原型链的对象时。 解…...
DNS的10种资源记录
前言 在DNS(域名系统)中,常见的资源记录(Resource Records, RR)用于存储域名与IP地址、邮件服务器等网络资源之间的映射关系。以下是几种常见的DNS资源记录: 1. A记录(Address Record…...

【数据分享】1981-2024年我国逐日最低气温栅格数据(免费获取)
气象数据一直是一个价值很高的数据,它被广泛用于各个领域的研究当中。之前我们分享过来源于美国国家海洋和大气管理局(NOAA)下设的国家环境信息中心(NCEI)发布的1929-2024年全球站点的逐日最低气温数据(可查看之前的文章获悉详情&…...

Kafka进阶_1.生产消息
文章目录 一、Controller选举二、生产消息2.1、创建待发送数据2.2、创建生产者对象,发送数据2.3、发送回调2.3.1、异步发送2.3.2、同步发送 2.4、拦截器2.5、序列化器2.6、分区器2.7、消息可靠性2.7.1、acks 02.7.2、acks 1(默认)2.7.3、acks -1或all 2.8、部分重…...

百度世界2024:智能体引领AI应用新纪元
在近日盛大举行的百度世界2024大会上,百度创始人李彦宏以一场题为“文心一言”的精彩演讲,再次将全球科技界的目光聚焦于人工智能(AI)的无限可能。作为一名科技自媒体,我深感这场演讲不仅是对百度AI技术实力的一次全面…...

NIST 发布后量子密码学转型战略草案
美国国家标准与技术研究所 (NIST) 发布了其初步战略草案,即内部报告 (IR) 8547,标题为“向后量子密码标准过渡”。 该草案概述了 NIST 从当前易受量子计算攻击的加密算法迁移到抗量子替代算法的战略。该草案于 2024 年 11 月 12 日发布,开放…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...

企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...