“递归调用或等价的显式栈在任一时刻保存一条 DFS 树根到当前顶点的活动路径。对白—灰—黑三色状态,白色尚未发现,灰色已发现但未完成,黑色已经完成。时间区间满足括号定理:任意两个顶点的区间”
形式陈述 ​
栈是抽象数据类型的一个实例,其合同只暴露后进先出的 push、pop 与 top 行为,存储布局和扩容策略不属于定义。
栈支持 push(x)、pop()、top(),并满足后进先出:若在无中间删除时依次压入 pop 或 top 的行为必须由规格明确。
直觉
栈把所有更新集中在顶部这一端,保持后进先出:最后进入的元素最先离开。它把尚未完成的嵌套任务按进入顺序压入,最近开启者最先收束,因此与递归调用、括号匹配和深度优先遍历天然同构。栈的关键是这种可观察顺序,而不是使用数组还是链表;数组实现只需一个顶部索引,链式实现则在表头插删。
例子与边界
括号匹配时,遇左括号压栈,遇右括号检查并弹出最近未匹配的左括号。调用栈记录嵌套函数活动。若允许从中间任意删除,就不再是纯栈接口。
扫描括号串 ([]) 时,遇到左括号依次压栈,右括号必须与栈顶类型匹配并弹出,最终栈空才合法。表达式求值中,运算符栈保存尚待结合的操作,优先级决定何时弹出。
栈下溢表示对空栈 pop,必须定义错误行为;固定数组还可能上溢。调用栈保存的不只是返回地址,还可能含局部变量和异常处理信息,深递归会耗尽系统栈;显式栈可以控制内存与遍历顺序。
推论与应用
深度优先搜索、表达式求值、语法解析和回溯依赖 LIFO 次序;双端队列只使用同一端时可实现这组操作。顺序 RAM 中,动态数组或链表可给 push、pop、top 的摊还或最坏
单调栈可在线性扫描中为每个元素寻找支配边界,Cartesian Tree把这组弹栈关系固化为同时满足中序与堆序的树。平衡括号树表示则利用 DFS 的入栈/出栈生成括号序列,再在该序列上支持导航。若要共享尾部并保留历史版本,应使用持久化数据结构的版本语义,而不是把普通数组栈直接称为持久化。
参考资料
- Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, Introduction to Algorithms, 4th ed., MIT Press, 2022, §10.1。
- Robert Sedgewick and Kevin Wayne, Algorithms, 4th ed., Addison-Wesley, 2011, §1.3。