1. 栈的基础概念与特性解析
栈(Stack)是计算机科学中最基础且重要的数据结构之一,它的核心特性可以概括为"后进先出"(LIFO, Last In First Out)。想象一下餐厅里叠放的餐盘——最后放上去的餐盘总是最先被取用,这就是栈的典型生活场景类比。
在程序设计中,栈主要包含两个基本操作:
- 压栈(Push):将元素添加到栈顶
- 弹栈(Pop):移除并返回栈顶元素
此外,通常还会提供:
- 查看栈顶(Peek/Top):获取但不移除栈顶元素
- 判空(isEmpty):检查栈是否为空
- 获取大小(Size):返回栈中元素数量
栈的底层实现通常有两种方式:
- 数组实现:需要预先分配固定大小的内存空间
- 链表实现:可以动态增长,但每个节点需要额外存储指针
提示:在算法题中,数组实现的栈通常效率更高,因为内存连续访问更快;而链表实现的栈在内存受限或不确定最大容量的场景下更有优势。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 栈的典型应用场景剖析
2.1 函数调用栈
程序执行时,每个函数调用都会在栈中创建一个栈帧(Stack Frame),包含:
- 局部变量
- 函数参数
- 返回地址
- 上一栈帧的指针
当函数返回时,对应的栈帧会被弹出,控制权交还给调用者。这个过程完美体现了栈的LIFO特性。
2.2 表达式求值
栈在表达式计算中扮演着关键角色,特别是处理:
- 中缀表达式转后缀表达式
- 后缀表达式(逆波兰表示法)求值
例如计算 3 + 4 * 2 / (1 - 5):
- 转换为后缀形式:
3 4 2 * 1 5 - / + - 使用操作数栈和运算符栈配合计算
2.3 括号匹配检查
栈是检查括号嵌套是否合法的理想数据结构:
python复制def is_valid(s: str) -> bool:
stack = []
mapping = {')': '(', '}': '{', ']': '['}
for char in s:
if char in mapping:
top = stack.pop() if stack else '#'
if mapping[char] != top:
return False
else:
stack.append(char)
return not stack
2.4 浏览器前进后退
浏览器的历史记录管理就是典型的双栈应用:
- 前进栈:存储可以前进访问的页面
- 后退栈:存储可以后退访问的页面
当点击后退时,当前页面压入前进栈,从后退栈弹出页面;前进则相反。
3. 栈的算法实战技巧
3.1 单调栈应用
单调栈是指栈内元素保持单调递增或递减的特殊栈结构,常用于解决"下一个更大元素"类问题。
例题:每日温度
给定每日温度列表,计算每天需要等待多少天才能遇到更高温度。
解法:
python复制def dailyTemperatures(T):
stack = []
res = [0] * len(T)
for i, t in enumerate(T):
while stack and T[stack[-1]] < t:
prev = stack.pop()
res[prev] = i - prev
stack.append(i)
return res
3.2 递归与栈的关系
所有递归算法都可以用栈改写为非递归形式。以二叉树中序遍历为例:
递归版本:
python复制def inorder(root):
if root:
inorder(root.left)
print(ro
