mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
1041 字
5 分钟
python算法学习之栈
2026-01-17

#

栈是一种 Last In First Out(LIFO)的线数据结构,它遵循后进先出的原则,即新添加的元素会排在栈的顶部,而访问的元素会排在栈的底部。栈可以用数组或链表实现。 栈的实现可以使用数组或链表,栈的核心操作:

  1. 入栈(Push):添加元素到栈顶
  2. 出栈(Pop):移除栈顶元素
  3. 查看栈顶(Peek/Top):查看但不移除栈顶元素
  4. 判断空(isEmpty):检查栈是否为空

栈就像一叠盘子:

  • 你只能从最上面取盘子(后进先出)
  • 新盘子只能放在最上面

例如

  1. 数组实现(顺序栈) - 使用列表

    stack = [] # 底部 顶部
    stack.append(1) # [1]
    stack.append(2) # [1, 2] ← 顶部
    stack.append(3) # [1, 2, 3] ← 顶部
    stack.pop() # 移除3 → [1, 2]
  2. 链表实现(链式栈) - 使用链表节点

    class Node:
    def __init__(self, value):
    self.value = value
    self.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()) # 3
print("出栈:", arr_stack.pop()) # 3
print(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 → None
print("栈顶:", ll_stack.peek()) # 3
print("出栈:", ll_stack.pop()) # 3
print("链表栈:", 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.0
print("(3 + 5) * 2 =", evaluate_expression("(3 + 5) * 2")) # 16.0
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

python算法学习之栈
https://tclothes.online/posts/算法2/sf2/
作者
衣服修改
发布于
2026-01-17
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时