【栈和队列】

目录

1,栈(Stack)

1.1 概念

1.2 栈的使用

1.3 栈的模拟实现

1.4 栈的应用场景

1.5 概念区分

1.6  使用链表来实现栈

2, 队列(Queue)

2.1 概念

2.2 队列的使用

2.3 队列模拟实现

3,双端队列 (Deque)

4,面试题

4.1 用队列实现栈

4.2 用栈实现队列


1,栈(Stack)

1.1 概念

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

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

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

1.2 栈的使用

push():叫做压栈,往栈里面放元素

查看push源代码,是有返回值的,他的返回值代表入栈的元素

pop():叫做出栈,弹出栈顶元素

此时就弹出了56

我们查看pop的源代码,他的返回值代表出栈的元素

peek():获取栈顶元素,但是不删除

源码:

empty():检测栈是否为空

源码:

stack可以调用empty可以理解,为什么可以调用isEmpty,Stack里面并没有这个方法呀!!

观察到Stack继承了Vector,isEmpty方法在Vector这个类当中,所以也继承了Vector类当中的方法

1.3 栈的模拟实现

创建一个类,叫做MyStack,自己来实现一个栈

那怎么来表示这个栈呢?

可以用一个数组来表示,每次往数组的最后一个存储元素,删也是删最后一个

1,push

怎么来放呢,就可以用到前面讲过的,定义一个usedSize来记录元素个数,并在对应位置存放元素,usedSize为0,在0下标存放一个元素,记录这个元素(usedSize++),在存放usedSize++下标位置的元素,再次记录这个元素(usedSize++),依次进行!!!

还要考虑数组满了的情况,对其进行扩容!

2,pop    弹出一个元素

首先如果是空的,就不能弹出元素,可以抛一个异常

可以发现,当usedSize为4的时候,我们需要弹出3下标的元素,即弹出elem[ usedSize -1 ]即可

3,peek   获取栈顶元素

这就是我们自己实现的一个栈。

可以将这个自己实现的栈变成泛型:

1.4 栈的应用场景

1,改变元素的序列

2,将递归转化为循环(一般情况下会用栈)

比如:逆序打印链表

非递归实现:就可以申请一个栈,这个栈里面就去放节点,然后进行出栈打印,即为逆序打印

3,括号匹配

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

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

在括号匹配的时候,一定是最后一个左括号和第一个右括号是否匹配,如何找到最后一个左括号呢?使用栈来完成。

情况一:如果是在括号匹配的时候,申请一个栈,定义一个 i 下标来遍历字符串。遇到一个左括号把这个左括号放到栈里面,i++,又遇到一个左括号放到栈里面,当遇到右括号的时候,就和当前的栈顶元素去匹配。当遇到右括号时,让当前的这个右括号与栈顶元素进行匹配,匹配成功,就让当前栈顶元素进行出栈,i++,再去判断右括号与当前栈顶元素是否匹配,匹配成功,就让当前栈顶元素进行出栈。即括号是匹配的情况下,最后栈为空且字符串以遍历完成。

情况二:如果不匹配,同上只要是左括号都放到栈里面,当遇到右括号时,与栈顶元素不匹配,返回false

情况三:字符串还没有遍历完,栈已经空了的情况。如下面这种,左括号放到栈里面,当遇到右括号时,与栈顶元素匹配,但是 i 没有遍历完,栈已经空了

情况四:左括号放到栈里面,遇到右括号时,与栈顶元素进行匹配,弹出栈顶元素后,i 已经遍历完了,但是栈里面还有元素

4,逆波兰表达式求值

逆波兰表达式又叫做后缀表达式(将运算符写在操作数之后)

例如:

中缀表达式(平常所看到的表达式):2+(3*5)

对应的后缀表达式:235*+

推导:

运算:

题目描述:

示例:

给的是一个字符串数组,放到栈里面的应该是整型,所以要将数字字符转为整型。

所以可以写一个方法,判断拿到这个字符串是否为运算符

5,栈的压入,弹出序列 (上面第一题)

描述:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。

6,最小栈

描述:设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

在常数时间内(时间复杂度为O(1))检索到最小值,一个栈是不能完成的,需要申请两个栈,一个普通栈,一个最小栈。

那如何能拿到一个最小栈呢?

1.5 概念区分

栈、虚拟机栈、栈帧有什么区别呢?

栈是一种数据结构。

虚拟机栈:如定义的局部变量就存于虚拟机栈当中。

栈帧:调用方法的时候为他开辟的一块内存。

至此:刚刚实现的栈或者说Java集合类的Stack底层是一个数组。这种栈叫做顺序栈!!!

1.6  使用链表来实现栈

首先栈遵循后进先出的原则,并且时间复杂度为O(1)

如果是单链表,那么入栈和出栈最好从链表头进行入栈和出栈。

相反如果链表的尾部进行出栈入栈时间复杂度为O(N)。

如果是双向链表来实现栈,那么复杂度均是O(1),如果以后要用到链式栈,使用双向链表会更好!

那么就可以直接当栈来使用。

为什么会报错?因为List这个接口没有实现push这个方法,要用LinkedList来引用这个对象。

这样就可以直接使用了,我们查看push,pop的源码。源码里面采用的是头插和头删!

所以可以拿数组实现栈,也可以拿链表实现栈。

如果要用数组实现的栈就用Stack这个类。

要用链式栈,使用LinkedList引用,或者Deque(叫做双端队列,下面会讲到)引用就可以当中栈来使用。

2, 队列(Queue)

2.1 概念

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

例如:食堂打饭排队,先排队的先打饭

2.2 队列的使用

在Java中,Queue是个接口,底层是通过链表实现的。

三个红色框框为一组,三个绿色框框为一组,两组从结果上来说没有什么区别。

要看他们的区别,如add和offer都是入队操作。

add和offer都是向队列中添加一个元素,一些队列有大小限制,因此如果想在一个满的队列中加入一个新项:

  • add:此时调用 add() 方法就会抛出一个 unchecked 异常
  • offer:此时调用 offer() 方法会返回 false,可以在程序中进行有效的判断。

2.3 队列模拟实现

1,用链表来实现(源码里面用的链式实现)

首先队列遵循先进先出的原则,那么入队就可以从尾巴入,出队就可以从头部出

也可以入队从头部入,出队从尾巴出

我们可查看源码的offer:调用了add方法               进入add方法:源码实现的是尾插法

模拟实现Queue

2,用数组来实现队列

首先对头叫做first,队尾叫做last。

此时last遍历完了,数组满了

假设现在对头可以出,出掉12 23,那么我的对头为34。但是此时0,1下标还可以放元素,数组并没有满!!!

我们在数组满的时候让last指向first。可能first和last相遇代表数组为空,不管空还是满(后面解决),先让last走回来,此时就可以再次存放元素了。

那么这个数组就不是简单的数组了,这个数组循环利用了,把这个队列叫做循环队列。

相当于把这个数组卷起来!!! 现在这个数组是这个样子。

开始存放元素:

满或者空也不一定是在0位置,有可能last在7的时候first就进行出,一直出就可能是在7位置相遇。也可能last在7位置first就开始出,出到2位置又开始存,就也可能在2位置相遇。 

到目前位置:相遇的时候是空的,相遇的时候也可能是满的!!!没有解决问题。

如何判断空和满!

方案一:

usedSize!!!放一个数据usedSize++,us == 0 为空,us == 数组长度为满。

方案二:

定义一个Boolean类型的flg = false 第一次相遇为false,第二次相遇为true。以标记的形式来判断。

方案三:(此代码用方案三实现)

浪费一个空间。也就是假如你的数组长度是8,但是最多只放7个元素。

即last和first相遇时为空,last的下一个为first就为满

如何让last或者first从7走到0,不能是last++或者first++,这样会导致数组下标越界,我们可给出一个公式:last = (last + 1)% 数组长度

代码实现:

首先此时代码有点错误

3,双端队列 (Deque)

双端队列(deque)是指允许两端都可以进行入队和出队操作的队列,deque 是 “double ended queue” 的简称。 那就说明元素可以从队头出队和入队,也可以从队尾出队和入队。

普通的队列只能从队尾进对头出,如果是双端队列,这个队列两边都可以进出。

有头插,尾插,还有头删尾删

LinkedList是双端队列的链表形式。

ArrayDeque是双端队列的线性实现(操作的是数组)。 

对于这两个类(LinkedList,ArrayDeque),可以当作栈使用,也可以当作队列使用

4,面试题

4.1 用队列实现栈

首先一个队列是不能实现栈的,这两个是相互矛盾的,一个是先进先出,一个是先进后出。

既然一个队列达不到要求,就用两个队列来实现栈。

top:

代码实现:

4.2 用栈实现队列

还是一样的,一个栈是不能实现队列的。要申请两个栈。

代码实现:

至此,栈和队列都讲完了!!!

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

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

相关文章

【计算机组成原理】部分题目汇总

计算机组成原理 部分题目汇总 一. 简答题 RISC和CICS 简要说明,比较异同 RISC(精简指令集)注重简单快速的指令执行,使用少量通用寄存器,固定长度指令,优化硬件性能,依赖软件(如编译…

递归调用,将源路径下所有文件文件夹复制到目标路径中.

其实代码demo很简洁&#xff0c;只是逻辑有点绕&#xff0c;主要是要一层一层调用自己&#xff0c;要清楚当前是第几层调用&#xff0c;及递归调用时进的点和出的点在哪儿&#xff0c;一切就清晰明了了。 /// <summary>/// 删除指定目录下面的所有文件和文件夹/// </s…

C++学习合集

#整理到一块&#xff0c;方便查东西&#xff0c;顺便补充一些之前没有学习到的东西# 变量 char--1字节 short--2字节 int-4字节 long--4字节 long long(int)--8字节&#xff1b;准确来说变量的大小取决于编译器&#xff0c;1字节8个二进制位&#xff0c;其中最高位为符号位…

基于Java的火车订票管理系统【附源码】

火车订票管理登录 摘要&#xff1a;随着我国铁路交通的不断发展&#xff0c;简单的窗口售票模式已经不能满足方便人们出行的目的。采用先进的网络技术开发出方便快捷的火车票订票系统是现代客运业务发展的必然需求。本次设计的火车票订票系统通过访问主页&#xff0c;可以实现…

算法训练与程序竞赛题目集合(L4)

目录 L4-103 就不告诉你 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; L4-104 Wifi密码 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; L4-105 冠军魔术 输入格式&#xff1a; …

Flutter TIM 项目配置

目录 1. 设计说明 2. 参考资料索引 Flutter SDK 服务端 Rest API 腾讯后台 其他 3. TIM 整体架构 第一部分&#xff1a;APP 端 第二部分&#xff1a;腾讯服务器 第三部分&#xff1a;三方服务 第四部分&#xff1a;你自己的服务器 4. TIM SDK 集成 TUIK 含 UI 集成…

物联网系统运维——数据库部署

一.MySQL 1.概要 MySQL是一种关联数据库管理系统&#xff0c;关联数据:而不是将所有数据放在一个大仓库内&#xff0c;这样就增加了速度并提高了灵活性库将数据保存在不同的表中。性能高、成本低、可靠性好&#xff0c;已经成为最流行的开源数据库。 二.MySQL安装与配置 1. …

DataStructure.时间和空间复杂度

时间和空间复杂度 【本节目标】1. 如何衡量一个算法的好坏2. 算法效率3. 时间复杂度3.1 时间复杂度的概念3.2 大O的渐进表示法3.3 推导大O阶方法3.4 常见时间复杂度计算举例3.4.1 示例13.4.2 示例23.4.3 示例33.4.4 示例43.4.5 示例53.4.6 示例63.4.7 示例7 4.空间复杂度4.1 示…

redis-实战篇(8)达人探店

8、达人探店 8.1、达人探店-发布探店笔记 发布探店笔记 探店笔记类似点评网站的评价&#xff0c;往往是图文结合。对应的表有两个&#xff1a; tb_blog&#xff1a;探店笔记表&#xff0c;包含笔记中的标题、文字、图片等 tb_blog_comments&#xff1a;其他用户对探店笔记的…

网格处理库 pmp-library 编译及应用笔记 -- 已全部解决√

多边形网格处理库Polygon Mesh Processing Library&#xff0c;简称pmp-library的 编译及应用笔记 – 已全部解决√ 官网&#xff1a;https://www.pmp-library.org/index.html 代码&#xff1a;https://github.com/pmp-library/pmp-library 平台&#xff1a;Ubuntu1 20.04&…

Bandzip:打破压缩界限,文件管理更高效

名人说&#xff1a;&#xff1a;一点浩然气&#xff0c;千里快哉风。 ——苏轼 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、软件介绍1、Bandzip2、核心特点 二、下载安装1、下载2、安装 三、使用方法 很高兴…

C语言中操作符详解(二)

OK&#xff0c;今天继续为诸君带来有关C语言中操作符的讲解 一 . 位操作符 C语言中的位操作符我相信大家并不陌生&#xff0c;我们在之前就已经接触过了一些 位操作符&#xff08;位操作符的操作数只能是整数&#xff09;&#xff1a; &#xff08;1&#xff09;& &…

Origin较好用的科研绘图软件

推荐自己也在用的科研绘图软件Origin图所示&#xff1a; 图1 图2 图3

WMS项目测试点

这里写目录标题 最后附有图片 仓库系统 仓库 / 库区 仓库 新增仓库 编号 必填校验 字段长度校验 20为字符 数据类型校验 名称 必填校验 字段长度校验 20为字符 数据类型校验 备注 填写备注校验 字符长度限制 不填写备注校验 新增仓库之后是否可以通过查询仓库名称和仓库编号查询…

poi生成的excel,输入数字后变成1.11111111111111E+23

poi版本4.1.2 生成excel后&#xff0c;单元格输入数字&#xff0c;过长的话变成这样 解决&#xff1a;生成的时候设置单元格格式为文本格式 import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.FileOutputStream; imp…

数据结构与算法笔记:基础篇 - 初始动态规划:如何巧妙解决“双十一”购物时的凑单问题?

概述 淘宝的 “双十一” 购物节有各种促销活动&#xff0c;比如 “满 200 元减 50元”。假设你女朋友购物车中有 n 个&#xff08;n > 100&#xff09;想买的商品&#xff0c;它希望从里面选几个&#xff0c;在凑够满减条件的前提下&#xff0c;让选出来的商品价格总和最长…

学习笔记——路由网络基础——路由转发

六、路由转发 1、最长匹配原则 最长匹配原则 是支持IP路由的设备默认的路由查找方式(事实上几乎所有支持IP路由的设备都是这种查找方式)。当路由器收到一个IP数据包时&#xff0c;会将数据包的目的IP地址与自己本地路由表中的表项进行逐位(Bit-By-Bit)的逐位查找&#xff0c;…

一元线性回归模型 多元线性回归模型回归模型评估

本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文峰…

Vue41 ref属性

ref属性 ref是Vue提供的获取组件的属性 <template><div><h1 v-text"msg" ref"title"></h1><button ref"btn" click"showDOM">点我输出上方的DOM元素</button><MySchool ref"sch"…

若依微服务项目09 - swagger如何不显示某个模块的接口文档

在若依微服务项目中&#xff0c;如果不想暴露某个模块的swagger的接口文档&#xff0c;需要怎么做&#xff1f; 本文以ruoyi-gen模块进行举例说明。 默认情况下&#xff0c;可以看到这里包含了ruoyi-gen模块&#xff0c;我们要做的是&#xff0c;要将ruoyi-gen进行隐藏。 最终的…