栈(Stack)是计算机科学中最基础且最重要的数据结构之一,其简洁而强大的特性使其在算法设计、系统编程和软件开发中无处不在。本文将全面解析栈数据结构的核心概念、实现方式、典型应用场景以及高级变体,帮助读者深入理解这一基础数据结构的原理与实践。
文章目录
栈的基本概念与特性
什么是栈?
栈的核心特性
栈的ADT(抽象数据类型)定义
栈的实现方式
数组实现(顺序栈)
数组实现的优缺点:
链表实现(链式栈)
链表实现的优缺点:
实现方式选择建议
栈的经典应用场景
函数调用与程序执行
表达式求值与语法解析
括号匹配检查
浏览器历史记录
深度优先搜索(DFS)
撤销(Undo)功能
栈的基本概念与特性
什么是栈?
栈是一种线性数据结构,遵循 后进先出(Last In First Out, LIFO) 原则。这种数据结构可以想象为餐厅里的一叠盘子——新洗好的盘子总是放在最上面,而使用时也是从最上面取走。栈的这种特性使其成为处理特定类型问题的理想选择。
栈的核心特性
LIFO原则:最后入栈的元素将最先被移除,这是栈最本质的特征
受限访问:只能从栈顶(Top)访问元素,不能直接访问中间或底部元素
动态大小:栈的大小通常随操作动态变化(静态栈实现除外)
基本操作:只允许通过有限的几个标准操作来访问和修改内容
栈的ADT(抽象数据类型)定义
作为抽象数据类型,栈支持以下基本操作接口:
push(item):将元素压入栈顶
pop():移除并返回栈顶元素
peek()/top():返回栈顶元素但不移除
isEmpty():判断栈是否为空
isFull():判断栈是否已满(针对固定大小的实现)
size():返回栈中元素数量
这些操作的时间复杂度通常都是 O ( 1 ) O(1) O(1),这是栈高效性的关键所在。
栈的实现方式
栈作为一种抽象概念,可以通过不同的底层数据结构来实现。最常见的实现方式有基于数组和基于链表两种。
数组实现(顺序栈)
数组实现利用连续内存空间存储栈元素,通常更节省内存且访问效率高。
class ArrayStack:
def __init__(self, capacity=10):
self.capacity = capacity
self.stack = [None] * capacity
self.top = -1 # 栈顶指针初始化为-1表示空栈
def push(self, item):
if self.isFull():
raise Exception("Stack is full")
self.top += 1
self.stack[self.top] = item
def pop(self):
if self.isEmpty():
raise Exception("Stack is empty")
item = self.stack[self.top]
self.top -=