当前位置: 首页 > news >正文

【数据结构】栈与队列的“双向奔赴”

目录

前言

1.使用“栈”检查符号是否成对出现

2.使用“栈”实现字符串反转

3.使用“队列”实现“栈”

4.使用“栈”实现“队列” 


前言

什么是栈?

  • 栈(stack)是一种特殊的线性数据集合,只允许在栈顶按照后进先出LIFO(Last In First Out)进行数据操作;

为什么使用栈?

  • 常见应用场景:浏览器的前进与回退操作、虚拟机栈等;

如何使用栈?

  • 栈的实现结构可以是一维数组或链表实现
  • 用数组实现的栈叫做顺序栈。在Java中,顺序栈使用java.util.Stack类实现
  • 用链表实现的栈叫做链式栈。在Java中,链式栈使用java.util.LinkedList类实现;
  • 入栈(push):将新元素放入栈顶,只允许从栈顶一侧放入元素,类似于弹匣装弹,只能从弹匣口依次压入弹匣内;

  • 出栈(pop):只有栈顶元素才允许出栈,类似于枪射出子弹时,子弹从弹匣口依次进入枪体射出;

  • 时间复杂度:
  1. 访问指定位置的元素:O(n)        ——>需要依次遍历所有元素,所需元素可能在栈底
  2. 入栈和出栈:O(1)                      ——>只涉及栈顶

什么是队列?

  • 队列(queue)是一种线性数据结构,队列中的元素按照先入先出的规则从队尾进入,队头出队;按照实现机制分为:单队列、循环队列;

为什么使用队列?

  • 常见应用场景:KTV点歌列表、阻塞队列、线程池的任务队列等;

如何使用队列?

  • 队列的实现结构可以是数组或链表实现
  • 用数组实现的队列叫做顺序队列。在Java中,顺序队列使用java.util.ArrayDeque类实现;
  • 用链表实现的队列叫做链式队列。在Java中,链式队列使用java.util.LinkedList类实现;
  • 入队(enqueue):只允许从队尾的位置放入元素,类似于银行取号等待叫号办理业务;

  • 出队(dequeue):只允许从队头的位置移出元素;

  • 假溢出:使用数组实现队列,执行出队操作时,指向队头和队尾的指针会向后移,队尾指针移动到最后的时候,无法添加数据,即使数组中之前出队的位置还要空闲空间,这种现象就是“假溢出”。

1. 使用“栈”检查符号是否成对出现

 public static boolean isValid(String s ){HashMap<Character, Character> mappings = new HashMap<>();mappings.put('}','{');mappings.put(')','(');mappings.put(']','[');Stack<Character> stack = new Stack<>();for(int i=0;i<s.length();i++){char c =s.charAt(i);if(mappings.containsKey(c)){//当前字符是“右括号”char topElement = stack.isEmpty() ? '#' :stack.pop();char left = mappings.get(c);if(left != topElement){return false;}}else {//当前字符是"左括号"stack.push(c);}}return stack.isEmpty();}

解读:

  • 创建一个HashMap mappings,用于存储右括号和对应的左括号的映射关系;
  • 创建一个Stack stack,用于存储遍历过程中遇到的左括号,以便后续进行匹配检查;
  • 进入for循环,遍历输入的字符串s。在循环中,取出字符串中的每个字符c;
  • 如果当前字符c存在于 mappings 中,即为右括号,那么就从栈中弹出栈顶元素,然后检查该右括号对应的左括号是否与弹出的左括号匹配,如果不匹配则返回false;
  • 如果当前字符c不存在于 mappings 中,即为左括号,将其压入栈中;
  • 循环结束后,检查栈是否为空,如果栈为空则说明所有的括号都匹配,返回true,否则返回false;
  • 测试用例
   public static void main(String[] args) {String str ="{[(!)]}";System.out.println(isValid(str));}
  • 测试结果


 2. 使用“栈”实现字符串反转

public static void main(String[] args) {String str ="just do it";StringBuilder stringBuilder = new StringBuilder(str);//使用栈实现字符串反转Stack<Character> stringStack = new Stack<>();//入栈for(int i=0;i<str.length();i++){stringStack.push(str.charAt(i));}//出栈while (!stringStack.empty()){str +=stringStack.pop();}System.out.println(stringBuilder);}

解读:

  • 创建一个Stack stringStack,用于存储字符串中的字符;
  • 进入for循环,遍历输入的字符串str,将字符串中的每个字符依次压入栈中;
  • 使用while循环,当栈不为空时,依次从栈中弹出字符,并将其拼接到原字符串str的末尾;
  • 循环结束后,str中存储的就是原字符串str的反转结果;
  • 测试结果


3. 使用“队列”实现“栈”

public class MyStack{private Queue<Integer> queue1; //出栈队列private Queue<Integer> queue2; //入栈队列public MyStack(){queue1 = new LinkedList<Integer>();queue2 = new LinkedList<Integer>();}public void push(int x){queue2.offer(x);while(!queue1.isEmpty()){queue2.offer(queue1.poll());}Queue<Integer> temp = queue1;queue1 = queue2;queue2 = temp;}public int pop(){return queue1.poll();}public int top(){return queue1.peek();}public boolean empty(){return queue1.isEmpty();}@Overridepublic String toString() {return queue1.toString();}
}

解读:

  • 定义了一个名为 MyStack 的类,其中包含两个私有属性 queue1 和 queue2,分别表示出栈队列和入栈队列,并在构造函数中对它们进行了初始化;
  • push 方法用于入栈操作,将元素加入 queue2 中,然后通过循环将 queue1 中的元素逐个转移到 queue2 中,以确保新入栈的元素位于队列的头部(因为队列的特性是先进先出)。最后交换 queue1 和 queue2 的引用,使得 queue1 始终指向当前栈中的元素所在的队列;
  • pop 方法用于出栈操作,直接从 queue1 中弹出元素即可;
  • top 方法用于获取栈顶元素,直接返回 queue1 的头部元素;
  • empty 方法用于判断栈是否为空,直接返回 queue1 是否为空的结果;

用两个队列模拟栈的基本操作,通过不断在两个队列之间转移元素,使得栈的操作可以在队列上进行;

  •  测试用例
 public static void main(String[] args) {MyStack myStack = new MyStack();//入栈myStack.push(1);myStack.push(2);myStack.push(3);myStack.push(4);myStack.push(5);System.out.println("入栈后"+myStack);System.out.println("入栈后栈顶元素:"+myStack.top());//出栈myStack.pop();myStack.pop();myStack.pop();myStack.pop();myStack.pop();System.out.println("出栈后"+myStack);System.out.println("出栈后栈是否为空:"+myStack.empty());}
  • 测试结果


4. 使用“栈”实现“队列” 

public class Queue{//入队栈private Stack<Integer> inStack = new Stack<>();//出队栈private Stack<Integer> outStack = new Stack<>();//入队public void offer(int item){while(!outStack.empty()){inStack.push(outStack.pop());}//新元素入队inStack.push(item);}//出队public int poll(){while(!inStack.empty()){outStack.push(inStack.pop());}return outStack.pop();}//判断是否为空public boolean empty(){return outStack.size() == 0 && inStack.size() == 0;}@Overridepublic String toString() {return inStack.toString();}
}

解读:

  • offer 方法用于向队列中添加元素。首先,它会将 outStack 中的元素逐个弹出并压入 inStack 中,这样可以确保之前入队的元素在 inStack 的底部,新的元素可以被放在队列的末尾,接着,将新元素直接入栈到 inStack 中,表示将新元素放入队列中。
  • poll 方法用于从队列中取出元素。首先,它会将 inStack 中的元素逐个弹出并压入 outStack 中,这样可以确保队列的头部元素位于 outStack 的栈顶,然后,从 outStack 中弹出栈顶元素,并作为出队操作的结果返回。
  • empty 方法用于检查队列是否为空。只有当 inStack 和 outStack 都为空时,才表示整个队列为空;

基于两个栈实现队列的方法称为双栈法,通过巧妙地利用栈的特性,可以实现队列的先进先出(FIFO)功能。在实际应用中,双栈法可以用于需要频繁进行队列操作的场景,同时也可以作为栈和队列之间的一个有趣的数据结构转换方式。

  • 测试用例
 public static void main(String[] args) {Queue myQueue = new Queue();//入队myQueue.offer(1);myQueue.offer(2);myQueue.offer(3);myQueue.offer(4);myQueue.offer(5);System.out.println("入队后:"+myQueue);//出队myQueue.poll();myQueue.poll();myQueue.poll();myQueue.poll();myQueue.poll();System.out.println("出队后是否为空:"+myQueue.empty());}
  • 测试结果

相关文章:

【数据结构】栈与队列的“双向奔赴”

目录 前言 1.使用“栈”检查符号是否成对出现 2.使用“栈”实现字符串反转 3.使用“队列”实现“栈” 4.使用“栈”实现“队列” 前言 什么是栈&#xff1f; 栈&#xff08;stack&#xff09;是一种特殊的线性数据集合&#xff0c;只允许在栈顶按照后进先出LIFO&#xff…...

sqllab第二十七关通关笔记

知识点&#xff1a; union select 关键字过滤 通过<> /**/进行截断处理 un<>ion sel<>ect 没效果uni/**/on sel/**/ect 被过滤了双写绕过 这关对select进行了多重过滤&#xff0c;无法进行双写绕过 大小写绕过 UNion SElect (这关可以用&am…...

助推直播产业升级与经济转型 天府锋巢直播产业基地成都开园

2023年年末&#xff0c;位于成都天府新区兴隆湖板块的天府锋巢直播产业基地正式开园&#xff0c;为成都直播产业注入了新的活力&#xff0c;助推成都经济转型和产业升级。天府锋巢直播产业基地的成立&#xff0c;不仅是成都直播产业的一大盛事&#xff0c;更是对成都经济发展的…...

VSCode+python单步调试库代码

VSCodepython单步调试库代码 随着VSCode版本迭代更新&#xff0c;在最新的1.87.x中&#xff0c;使用Python Debugger扩展进行调试时&#xff0c;扩展的justMyCode默认属性为true&#xff0c;不会进入库中的代码。这对debug而言不太方便&#xff0c;因此需要手动设置一下&#…...

如何使用EMC测试软件执行辐射抗扰度测试?(三)软件检查及手动模式

一、前言 之前的文章为大家介绍了使用EMC测试软件执行辐射抗扰度测试的测试方法、频率变化模式测试方法、校准方法及调制。本期文章继续为大家介绍软件检查和手动模式两部分内容。 前文回顾&#xff1a; 如何使用EMC测试软件执行辐射抗扰度测试&#xff1f;&#xff08;一&am…...

云手机为电商提供五大出海优势

出海电商行业中&#xff0c;各大电商平台的账号安全是每一个电商运营者的重中之重&#xff0c;账号安全是第一生产力&#xff0c;也是店铺运营的基础。因此多平台多账号的防关联管理工具成了所有电商大卖家的必备工具。云手机最核心的优势就是账户安全体系&#xff0c;本文将对…...

chatgpt大模型基础学习

chatgpt大模型基础学习 1. 吴恩达提示工程2. 大模型说的token是什么 1. 吴恩达提示工程 知乎 https://zhuanlan.zhihu.com/p/626290417?utm_id0 中文版 https://mp.weixin.qq.com/s?__bizMzkwMjQ5MzExMg&mid2247483714&idx1&sn5e905f5ec6196f6dc2187db2a8618f02&…...

代码随想录算法训练营第14天 part01 | 二叉树理论基础篇

代码随想录 二叉树理论基础篇 二叉树的种类 二叉树有两种主要的形式&#xff1a;满二叉树和完全二叉树 满二叉树&#xff1a;如果一棵二叉树只有度为0的结点和度为2的结点&#xff0c;并且度为0的结点在同一层上&#xff0c;则这棵二叉树为满二叉树。 这棵二叉树为满二叉树…...

async与defer的区别

原文解释 async vs defer attributes - Growing with the Web...

奇数乘积(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int i 1;int j 3;//循环运算&#xff1b;while (j < 12){//运算&#xff1b;i i * j;//改变数值&#xff1b;j 2…...

中文分词库:jieba的词性对照表

jieba词性对照表 字母词性a形容词ad副形词ag形容词性语素an名形词b区别词c连词d副词dg副词素e叹词f方位词g语素h前接成分i成语j简称略称k后接成分l习用语m数词mq数量词n名词ng名词性语素nr人名ns地名nt机构团体名nz其他专名o拟声词p介词q量词r代词rg代词性语素rr人称代词rz指示…...

Linux:git的基础操作

git的下载 版本控制系统一般分为两种&#xff0c;集中式版本控制系统&#xff0c;分布式版本控制系统 什么是集中式版本控制系统&#xff1a;版本库集中存放在中央服务器&#xff0c;工作时候使用自己的电脑&#xff0c;当工作时候在中央服务器上拉取最新版本的代码&#xff0c…...

【华为OD机试】CPU 算力分配【C卷|100分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 现有两组服务器A和B,每组有多个算力不同的CPU,其中 A[i] 是 A 组第 i 个CPU的运算能力, B[i] 是 B组 第 i 个CPU的运算能力。 一组服务器的总算力是各CPU的算力之和。 为了让两组服务器…...

挑战杯 机器视觉目标检测 - opencv 深度学习

文章目录 0 前言2 目标检测概念3 目标分类、定位、检测示例4 传统目标检测5 两类目标检测算法5.1 相关研究5.1.1 选择性搜索5.1.2 OverFeat 5.2 基于区域提名的方法5.2.1 R-CNN5.2.2 SPP-net5.2.3 Fast R-CNN 5.3 端到端的方法YOLOSSD 6 人体检测结果7 最后 0 前言 &#x1f5…...

基于Spring Boot的社区便民服务管理系统的设计与实现

摘 要 二十一世纪我们的社会进入了信息时代&#xff0c;信息管理系统的建立&#xff0c;大大提高了人们信息化水平。传统的管理方式对时间、地点的限制太多&#xff0c;而在线管理系统刚好能满足这些需求&#xff0c;在线管理系统突破了传统管理方式的局限性。于是本文针对这一…...

亚信安慧AntDB:数字化创新背后的数据力量

亚信安慧AntDB的“融合实时”的特性&#xff0c;不仅使得数据库具备了更强大的适应性&#xff0c;更让企业在不同业务场景下能够更好地实现业务目标&#xff0c;释放出更大的商业价值。融合实时的特性让AntDB具有了高度灵活性和实时性&#xff0c;使其能够满足企业在不同业务需…...

Matplotlib数据可视化实战-1数据可视化Matplotlib基础

1.1绘图的一般过程&#xff1a; 1.导入相关库 2.生成、读入或计算得到数据&#xff1b; 3.根据需要绘制折线图、散点图、柱状图、饼状图、雷达图、箱线图、三维曲线/曲面以及极坐标系图形&#xff1b; 4.根据需要设置图形属性&#xff1b; 5.显示或保存绘图结果。 例如&…...

信也科技发布消费者权益保护2023年度报告: 科技驱动、服务为先、合作共建社会化消保体系

3月15日消费者权益日当天&#xff0c;信也科技发布《消费者权益保护2023年度报告》&#xff08;下称《报告》&#xff0c;消费者权益保护简称“消保”&#xff09;。该报告为信也科技消保委员会成立后首份公开披露的消保工作年度总结。《报告》显示&#xff0c;信也科技通过智能…...

REDHAWK——连接(续)

文章目录 前言一、突发 IO1、数据传输①、输入②、输出 2、突发信号相关信息 (SRI)3、多输出端口4、使用复数数据①、在 C 中转换复数数据 5、时间戳6、端口统计①、C 二、消息传递1、消息生产者①、创建一个消息生产者②、发送消息 2、消息消费者①、创建消息消费者②、注册接…...

9.Python从入门到精通—Python 字符串格式化,三引号,Unicode 字符串

9.Python从入门到精通—Python 字符串格式化,三引号,Unicode 字符串 Python 字符串格式化Python 三引号Unicode 字符串创建 Unicode 字符串Python 的字符串内建函数 Python 字符串格式化 Python中的字符串格式化是指将一个字符串中的占位符替换为指定的值。Python中有多种字符串…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

uniapp 小程序 学习(一)

利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 &#xff1a;开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置&#xff0c;将微信开发者工具放入到Hbuilder中&#xff0c; 打开后出现 如下 bug 解…...

数据结构:递归的种类(Types of Recursion)

目录 尾递归&#xff08;Tail Recursion&#xff09; 什么是 Loop&#xff08;循环&#xff09;&#xff1f; 复杂度分析 头递归&#xff08;Head Recursion&#xff09; 树形递归&#xff08;Tree Recursion&#xff09; 线性递归&#xff08;Linear Recursion&#xff09;…...