如何理解“栈”?
-
叠盘子\
-
放:从下往上一个个的放\
-
取:从上往下一个个的取
-
-
栈特点
- 后进先出,先进后出
- 操作受限的线性表,数组和链表功能上完全可以代替栈 但是栈针对更特殊的场景,可以避免使用者的误用
-
什么时候使用栈:在一端插入和删除数据,并且满足后进先出、先进后出的特性
\
如何实现一个“栈”?
-
栈的操作:出栈和入栈
-
栈的数据结构:数组(顺序栈) 链表(链式栈)
- 个人感觉链表更加适合栈 不需要移动大量元素,可以利用内存碎片,并且不需要支持随机访问
-
时间复杂度:所有的操作时间复杂度都是o(1)
-
实现动态扩容的顺序栈
- 使用 list 链表
- 出栈时间复杂度是o(1)
- 入栈时间复杂度最好o(1),最差是o(n) 使用均摊时间复杂度分析o(1) (1+1+1+1+1+....+n)/n=1
\
栈的应用
栈在函数调用中的应用
- 操作系统给每个线程分配了一块独立的内存空间,用作存储函数的临时变量\
\
栈在表达式求值中的应用
-
根据加减乘除进行四则运算(10以内)
-
具体实现
-
数据结构:两个栈,一个保存操作数,一个保存运算符
-
从左开始遍历,遇到数压入操作数栈
-
遇到运算符就与栈顶元素进行比较
- 如果比运算符栈顶元素的优先级高,就将当前运算符压入栈
- 如果比运算符栈顶元素的优先级低或者相同,从运算符栈中取栈顶运算符,并取出两个数,计算后压入栈顶
-
\
栈在括号匹配中的应用
-
可以用于括号的匹配状态
-
实现
- 发现左括号压入栈
- 发现右括号取出栈顶元素比较,相等继续,不相等则不匹配
- 最后判断栈是否为空
浏览器中的应用
-
实现
- 用两个栈实现前进和后退
- 首次访问页面压入栈x,点击后退出栈放入到y中 栈x为空则无后退
- 点击前进从y中出栈 栈y为空则无前进
\
总结
-
栈是一种操作受限的数据结构,只支持入栈和出栈操作\
-
不管基于数组还是链表,入栈、出栈的时间复杂度都为 O(1)\
-
动态栈在均摊时间复杂度后也是O(1)