java 栈和队列实现迷宫代码_栈和队列的构造和相互实现、最小栈

(给算法爱好者加星标,修炼编程内功)

作者:vitasoy25 / 在所不辞 (本文来自作者投稿)

问题描述

  1. 如何用数组实现固定长度的栈和队列?【基础】

  2. 如何只用队列实现一个栈?【有一定技巧】

  3. 如何只用栈实现一个队列?【有一定技巧】

  4. 如何实现一个最小栈,即一个具备返回最小值函数的栈?【有一定难度和技巧性】

使用数组实现固定长度的栈

对于大多数人而言,这题就是送分题,当然,在面试场景下,如何确保又快又准地完成这道题目,就需要考验我们的coding能力了,对于自认为基础较好的同学,建议花一两分钟思考下pushpop函数的设计,然后再往下看进行验证;对于自认基础一般的同学,建议花5-10 分钟写一下这个代码,写完再进行验证;对于没有学过的同学,建议看看思路即可。

废话少说,我们都知道栈的特性:先进后出,后进先出(FILO),因此,关键考虑点就是push函数和pop函数如何设计。

首先我们构建一个栈类:

class Stack {

push函数,首当其冲的就是边界考虑,如果栈已经满了,我们不能继续加到数组中,否则会溢出;至于push进去,我们使用size++非常方便和简洁,因为size一开始是0,而第一个位置的下标也是0,当我们推入一个数字后,size又应该增加一。

void push(int num) {

pop函数,依然要考虑边界,如果栈已经是空的了,那么就不能继续推出;至于被推出的数据我们并不需要做特殊的处理,实际上我们只需要标记好栈的当前长度即可。

int pop() {

另外,这里我们模仿了java中的栈的弹出写法,不像cpp中为无返回值,我们会返回被推出的数的值。

使用数组实现固定长度的队列

所谓队列,即先进先出,后进后出(FIFO)的结构。有了前面写栈的经验,这里就不多说了,重点依然是边界,当然队列我们需要充分利用数组的空间,因此需要两个变量,分别记录开始和结尾。

构造队列类:

class Queue {

push函数:

void push(int num) {

要注意,当end到达数组的末尾,但当前长度 < 数组大小时,说明数组前部分还有空位(即begin > 0)。

40cf0cf482c17ebe2a3d383e7444acd6.png
压入边界

如果sizearr.size() - 1相等,说明当前队列已经到达末尾了,end需要回到开头;否则,end向后移即可。

pop函数:

int pop() {

关于这句begin = (begin == arr.size() - 1) ? 0 : begin + 1;,如果begin到达了队列的末尾,此时pop弹出,那么begin需要回到数组开头,否则,begin自增即可。

6df17a26b47612ba31b54e1bf39262a4.png
弹出边界

如何只用队列实现一个栈

只用队列实现栈,没有接触过这道题的同学,咋一看会比较懵逼,但实际上往往是忽略了队列的个数。事实上我们可以使用两个队列来实现。

如下图所示,我们使用两个队列queuehelp来实现这个栈:

首先我们先在queue˙中放入三个数,注意这里使用的是队列,此时我们想要弹出3,而队列只能取最前面的数,因此我们要另辟蹊径:

  1. queue.size() > 1,将queue的队首弹出并压入help中;

  2. queue.size() > 1,将queue的队首弹出并压入help中;

  3. queue.size() == 1,暂存当前队首(栈顶元素),这是我们待会要返回出去的数;

9fa8285d9646c4d1c63dffae3af34b21.png
获取栈顶元素
  1. 也是最关键的一步,我们将queuehelp交换:

  2. 返回前面暂存的栈顶元素即可。

1f4f325b7eb4451fa3ec01073864d3f6.png
交换队列

至此,我们相当于完成了pop函数,而push函数,实际上判断一下边界(如果有的话),存入queue中即可。

代码实现:

class Stack{

如何只用栈实现一个队列

有了前面用队列实现栈的经验,接下来考虑用栈实现队列也会更加简单。同样的,我们使用两个栈来实现队列。

队列是先进先出,而栈是后进先出,那么我们怎么用栈实现呢?脑子灵光的同学们可能已经想到了:把一个栈倒入另一个栈里:

57e7d9d8caf4eb9ef6038dd788e54605.png
倒栈

关键部分来了,我们只需每次倒栈的时候将pushStack中的数据全部倒入popStack,且popStack为空时才进行倒栈操作即可。(大家可以思考一下为什么?)

倒栈操作实现:

void pushToPop() {

其他部分代码:

class Queue{

如何实现一个最小栈,即一个具备返回最小值函数的栈?

这一题就比较有意思了,我们如何实现一个栈,能随时的获取这个栈里面的最小值呢?可能有朋友会不假思索的说这很简单,用一个变量来存最小值就好了。嘿,这就忘了一点了,栈是会变化的,假如当前栈顶是最小值,你弹出之后,去哪里找次小值呢?

bf95b1046c0ac8798a27ab4d63da4453.png
只用一个变量存储最小值是行不通的

大部分同学在此处就会懵逼了,那应该怎么做呢?

其实很简单,我们再拿一个栈来存储最小值即可:即我们有一个dataStack和一个minStack,前者存储数据,后者存储最小值;那么最小值该怎么存呢?

和数据栈并行的存,也就是说最小栈的长度和数据栈的长度一致,每个数据代表同等长度下的栈的最小值

画个图你们就明白了:

0c92a9d7591cf4c556f3d9a43c931e4a.png
压栈
  1. 当我们一开始压入2时,因为此时minStack,所以直接压入即可;

  2. 当我们压入3的时候,此时3 > minStack.top()3 > 2,因此,我们压入当前的最小值2

  3. 当我们压入1的时候,此时1 < minStack.top()1 < 2,因此,我们压入新的最小值1

  4. 弹栈操作则更加简单,minStack只需跟随dataStack进行弹栈即可。

代码实现如下:

class MinStack {

【本文作者】

在所不辞:双非一本,科班出身;大二即进入腾讯实习,目前专注写面试相关的算法、计算机网络、操作系统等基础知识;助力研发面试,共同成长!

推荐阅读   点击标题可跳转

算法一看就懂之「 堆栈 」

图解堆算法、链表、栈与队列

觉得本文有帮助?请分享给更多人

关注「算法爱好者」加星标,修炼编程内功

cc6b60d99b2673d88be4fb53d946456c.png

好文章,我在看❤️

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值