本文并不着墨于栈的基础,更多的是基于栈的个人思考和使用的场景还有LeetCode上对应的题目
一、栈是什么?
栈这种数据结构,记住一点:FILO(first input last output),先进后出
就像是枪的弹夹,先放入的子弹,会在最后被射出,就像是叠盘子,最晚放上来的盘子,因为在最上面所以会被我们先拿出来用。
所以栈这种数据结构,是一种有限制的数据结构,我拿数据的时候,必须拿栈顶的数据,不能直接拿下面的(只能在数据的一端做删除和插入操作)
二、为什么用栈?
那么问题来了,既然有这样麻烦的限定,为什么栈这种数据结构还能存在呢?其实我们可以很轻松的使用数组或链表来实现栈这种数据结构,但是数组和链表其实提供了更多的操作,操作上灵活,但使用的时候可能会因为选择多而导致不可控(其实更多的是写代码时候,对应的场景用对应的数据结构,写起来更顺手,使用方便,甚至性能会更好)
三、什么场景用栈?
场景一:浏览器前进后退
这个案例来自于王争老师的《算法与数据结构之美》,图片也是他的,我只是搬运工!!!
我们依次访问了a,b,c三个页面
这时候,你想回看b页面!!就要把c弹出,放入Y
然后你从b页面又访问了d页面,那么就清空Y,在X中加入d
场景二:实现各类计算器
大家可以百度下,传入一个字符串的中缀表达式,如何计算得到最后的结果?
比如:(12+23)*13-2,这样的式子,我们需要考虑四则运算的优先级和括号的优先级,这种需求,就是用栈来实现的,有一篇写得很不错博客跟大家分享,大体思想就是把人类能够读懂的中缀表达式,转换成前缀(波兰)或者后缀(逆波兰)表达式,然后使用栈的数据结构进行运算
前缀、中缀、后缀表达式(逆波兰表达式)(作者:chensongxian):https://www.cnblogs.com/chensongxian/p/7059802.html
场景三:java程序的字节码指令
其实你认真想下,java在执行两个数相加的操作的时候,是如何做的?
截图出自我以前的文章,大家对这块有兴趣可以去看看,之前我有对这方面的知识做一些收集和总结
【java】对字节码的理解和整理:https://blog.youkuaiyun.com/lsr40/article/details/93598693
思考下,为什么会是这样?
不就是因为,我们在执行代码的时候,A方法调用B方法,那么就要B方法先执行完,再回到A方法中,这不就是先入后出的概念吗?!(其实我觉得也有一点点像递归)
四、相关题目
下列是LeetCode有关栈的题号:(解法我就不写了,LeetCode上的答案和思路,肯定比我的好多了)
20,155,232,844,224,682,496
当然并不是所有题目用stack才是最优解,只是说用stack想法,会比较好解决这类问题!
大家如果有任何问题,都可以在评论区留言吧(关于LeetCode题目的想法也可以)~
最近也是感觉好长一段时间没写文章了,但这不代表我没有学习,在做输出前,肯定是需要更多时间更多知识的输入的,最近其实在补自己的基础:《数据结构和算法》。我发现自己是一个挺浮躁的人,老是不愿意做打基础的事情(比如踢足球,我也不爱练基本功),这样可能前期成长很快,但是地基打不牢固,高楼的倾倒也仅在顷刻之间(而且我也只是半桶水,还算不上什么高楼),所以既然想在这行走下去,就必须花时间弥补之前的遗漏!
加油!!
最近看到一句话:既定命运早已经写好,何须今日才盖棺定论
大概意思就是说,平时你不努力,那么你的挫折与失败早就写在了每一个放纵自我的夜晚,并不需要今天才来下结论是造化弄人,共勉吧!