1041 字
5 分钟
python算法学习之栈
栈
栈是一种 Last In First Out(LIFO)的线数据结构,它遵循后进先出的原则,即新添加的元素会排在栈的顶部,而访问的元素会排在栈的底部。栈可以用数组或链表实现。 栈的实现可以使用数组或链表,栈的核心操作:
- 入栈(Push):添加元素到栈顶
- 出栈(Pop):移除栈顶元素
- 查看栈顶(Peek/Top):查看但不移除栈顶元素
- 判断空(isEmpty):检查栈是否为空
栈就像一叠盘子:
- 你只能从最上面取盘子(后进先出)
- 新盘子只能放在最上面
例如
-
数组实现(顺序栈) - 使用列表
stack = [] # 底部 顶部stack.append(1) # [1]stack.append(2) # [1, 2] ← 顶部stack.append(3) # [1, 2, 3] ← 顶部stack.pop() # 移除3 → [1, 2] -
链表实现(链式栈) - 使用链表节点
class Node:def __init__(self, value):self.value = valueself.next = None
二、栈的实现方式
1. 数组实现
class ArrayStack: """基于数组的栈实现""" def __init__(self, capacity=10): self.capacity = capacity self.stack = [None] * capacity # 预分配固定大小 self.top = -1 # 栈顶指针,-1表示空栈
def __str__(self): if self.is_empty(): return "Stack: []" return f"Stack: {self.stack[:self.top + 1]}"
def is_empty(self): """判断栈是否为空""" return self.top == -1
def is_full(self): """判断栈是否已满""" return self.top == self.capacity - 1
def push(self, value): """入栈操作 - O(1)""" if self.is_full(): self._resize() # 动态扩容 self.top += 1 self.stack[self.top] = value
def pop(self): """出栈操作 - O(1)""" if self.is_empty(): raise IndexError("Pop from empty stack") value = self.stack[self.top] self.stack[self.top] = None # 可选:帮助垃圾回收 self.top -= 1 return value
def peek(self): """查看栈顶元素 - O(1)""" if self.is_empty(): raise IndexError("Peek from empty stack") return self.stack[self.top]
def size(self): """获取栈的大小 - O(1)""" return self.top + 1
def _resize(self): """动态扩容 - O(n)""" self.capacity *= 2 new_stack = [None] * self.capacity for i in range(self.top + 1): new_stack[i] = self.stack[i] self.stack = new_stack测试数组栈
arr_stack = ArrayStack(3)arr_stack.push(1)arr_stack.push(2)arr_stack.push(3)print(arr_stack) # Stack: [1, 2, 3]print("栈顶:", arr_stack.peek()) # 3print("出栈:", arr_stack.pop()) # 3print(arr_stack) # Stack: [1, 2]2. 链表实现
class Node: """链表节点""" def __init__(self, value): self.value = value self.next = None
class LinkedListStack: """基于链表的栈实现""" def __init__(self): self.top = None # 栈顶节点 self._size = 0
def __str__(self): values = [] current = self.top while current: values.append(str(current.value)) current = current.next return " → ".join(reversed(values)) + " → None" if values else "Empty Stack"
def is_empty(self): return self.top is None
def push(self, value): """入栈 - O(1)""" new_node = Node(value) new_node.next = self.top # 新节点指向原栈顶 self.top = new_node # 更新栈顶 self._size += 1
def pop(self): """出栈 - O(1)""" if self.is_empty(): raise IndexError("Pop from empty stack") value = self.top.value self.top = self.top.next # 更新栈顶 self._size -= 1 return value
def peek(self): """查看栈顶 - O(1)""" if self.is_empty(): raise IndexError("Peek from empty stack") return self.top.value
def size(self): return self._size测试链表栈
ll_stack = LinkedListStack()ll_stack.push(1)ll_stack.push(2)ll_stack.push(3)print("链表栈:", ll_stack) # 1 → 2 → 3 → Noneprint("栈顶:", ll_stack.peek()) # 3print("出栈:", ll_stack.pop()) # 3print("链表栈:", ll_stack) # 1 → 2 → None三、栈的应用
1. 括号匹配
def is_valid_parentheses(s: str) -> bool: """LeetCode 20: 有效的括号""" stack = [] mapping = {')': '(', ']': '[', '}': '{'}
for char in s: if char in mapping.values(): # 左括号 stack.append(char) elif char in mapping.keys(): # 右括号 if not stack or stack[-1] != mapping[char]: return False stack.pop() else: continue # 忽略其他字符
return not stack # 栈空则所有括号匹配测试
test_cases = [ ("()", True), ("()[]{}", True), ("(]", False), ("([)]", False), ("{[]}", True), ]
for s, expected in test_cases: result = is_valid_parentheses(s) print(f"'{s}': {result} (预期: {expected})")2. 表达式求值
def evaluate_expression(expression: str) -> float: """计算表达式值(支持 + - * /)""" def apply_operator(operators, values): op = operators.pop() right = values.pop() left = values.pop() if op == '+': values.append(left + right) elif op == '-': values.append(left - right) elif op == '*': values.append(left * right) elif op == '/': values.append(left / right)
def precedence(op): if op in ('+', '-'): return 1 if op in ('*', '/'): return 2 return 0
operators = [] values = [] i = 0
while i < len(expression): # 跳过空格 if expression[i] == ' ': i += 1 continue
# 处理数字 if expression[i].isdigit(): j = i while j < len(expression) and (expression[j].isdigit() or expression[j] == '.'): j += 1 values.append(float(expression[i:j])) i = j
# 处理左括号 elif expression[i] == '(': operators.append('(') i += 1
# 处理右括号 elif expression[i] == ')': while operators and operators[-1] != '(': apply_operator(operators, values) operators.pop() # 移除 '(' i += 1
# 处理运算符 else: while (operators and operators[-1] != '(' and precedence(operators[-1]) >= precedence(expression[i])): apply_operator(operators, values) operators.append(expression[i]) i += 1
# 应用剩余运算符 while operators: apply_operator(operators, values)
return values[-1] if values else 0测试
print("3 + 5 * 2 =", evaluate_expression("3 + 5 * 2")) # 13.0print("(3 + 5) * 2 =", evaluate_expression("(3 + 5) * 2")) # 16.0部分信息可能已经过时









