数据结构 (3)栈与队列之粗心的人如何写oj血的教训

栈是种特殊的线性表,他先入后出后进先出
入数据为压栈,且在栈顶入,出数据为弹栈或者出栈,且在栈顶出

栈好比是枪,压子弹为入栈,射击为出栈

  • 压栈
    在这里插入图片描述
  • 出栈
    在这里插入图片描述

就像你啃鸡爪子一样,你从包装袋里拿出来,从上往下,一点一点的啃,你想下,或者去买个试试看

在这里插入图片描述
案例:
1234依次进栈出栈顺序是什么样?
后文解答

实现

  • 那么这么实现,有俩种方法
  1. 顺序表
  2. 链表

那种方法更优?其实是顺序表为啥!!为啥不是链表?听我徐徐道来

栈的结构先进后出,后进先出,如果(单)链表来实现栈,栈顶只有头插方便,栈尾插太麻烦,用双向带头链表又显的大题小作了,且他们要更改节点的链接关系,用顺序表就不一样了,把栈顶设为尾插,出栈覆盖完美解决


带着疑惑看文章:

  1. 他和顺序表的区别在哪
    栈的实现

队列

队列刚好与栈反过来,先入先出,后入后出,但是他也是单头出,单头插,但是他们不是在一个同一个口,进出,他们分工明确

是否记得上小学的时候,放学要排好队在一起走出校门,那么排在第一个(个子矮的)的就先出校门,排在(个子高的)最后出校门,可以把排队抽象成入队列,出校门为出队列

在这里插入图片描述

实现

  • 实现,有俩种方法
  1. 顺序表
  2. 链表

那种方法更优呢?可想而之肯定是列表毕竟顺序表的头插头删效率低,且麻烦,所以用链表,且是单链表!!为什么不用双链表,问就是懒,他需要链接太多了,用单链表标记一个尾,顺歪歪


队列的实现
案例:
1234依次进队列出队列的顺序是什么样?
后文解答



粗心的人如何写oj


  • 都说慢工出细活,那么粗心人一定做事火急火燎的

这种事情常常发生在我身上,写代码草草画个图感觉差不多了(还没理清楚细节),快速上手,写的时候下笔如有神,几分钟就敲完了,跑起来这错哪错,要么少打个单词,要么逻辑写反,复制变量把类型也复制…………这样小小的错误往往让我花了许多的时间排错,得不偿失.最重要的是死不悔改,都说吃了亏会长记性为什么,我却被打成大花脸!!!


括号匹配


题:

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合
左括号必须以正确的顺序闭合


案例:
在这里插入图片描述

示例3,与5,可以看出,俩个括号相对才是正确,且不能“夹心”。用奥利奥+开心消消乐来解释,左括号为奥,右括号为利奥+利就可吃掉(销毁),且他们口味必须相同口味组成才可以吃

在这里插入图片描述


思路:

这是一道栈的经典题,类似开心消消乐,如何实现?其实不难,遇到左边括号入栈,遇到右括号出栈,比较是否匹配


图解:
在这里插入图片描述


⚠️⚠️提醒
  1. 这题测试案例很多且刁钻,需要细心想出他的限制条件

题目链接


用队列实现栈


题:

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
如题所示用队列实现栈


题解:
上述所说,队列先进先出,而队列后先进后出,题目给了我们俩个队列,那么意图是让我们利用它.他们底层逻辑反如何操作呢?那么我们刚好可以把握这一点,我先把队列的 n-1 个数据移到另一个队列中,释放那留下的元素,上述操作找不空的那个队列及其重要


图解:

在这里插入图片描述


⚠️⚠️提醒

  • 防止粗心
  • 写题前先画图,捋清逻辑
  • 复制粘贴要看好,虽然复制粘贴可以省时间但是,粗心复排拍错话费他的10倍不止
  • 搞清楚盘空的条件,不要粗心看错了,一件事是否成功,往往在于小细节处理

题目链接


用栈实现队列


题目:

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false


题解:
俩个栈实现如何实现,其实不难,俩个栈,一个入数据,一个出数据,出队列时候,把如数据的栈的数据给出数据相当一次排序


在这里插入图片描述


⚠️⚠️提醒

  1. 判空,没错我又挖坑自己跳,血的教训(找错10分钟,改错几秒钟)

设计循环队列

设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(frist into frist out 先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。(但是使用循环队列,我们能使用这些空间去存储新的值)<–这里就类似RPG 战力排行类似,有新的大佬进来,老的就要被替换


思路
顺序表实现,创造一个循环循环队列,然后在此基础上增删查改,但是他有一个缺陷,如图:

在这里插入图片描述上面的情况,就无法判断循环队列满or不满,它们直接影响后面的增删查改


改进:
在上述基础上,开辟空间的时候在多开辟一个位置,那么即可分清队列是否满,只需判断尾指针的下一个是否与头指针相同(这都是在比下标),相同为满,不同为空


如何让顺序表循环呢?我还头次听,要怎么实现,来吧颠覆世界观的来了,只需把控他的下标,如果下标超过数组最大下标重制下标 ,这样顺序表就是循环的来

题目链接


代码链接


粗心的长征还没有到此结束,且我付出的代价也远远不止这些,可为什么“我”还没有长记性呢?俗话说:吃一垫长一智,而我对我来说现在这些错误对我来说如天边的浮云那般,没有引起我的注视,但我深刻他确实成长路上致命的杀手,我预估,我细心一点,我每天至少可以省下3个多小时,而我却觉得时间不够,这可能就是无意义的努力,我知道避免粗心的方法有一个,正念冥想,做题前进行几分钟的冥想可以减少错误.

猜你喜欢

转载自blog.csdn.net/Legwhite/article/details/119775679