📜  堆栈python的应用(1)

📅  最后修改于: 2023-12-03 14:51:37.765000             🧑  作者: Mango

堆栈 Python的应用

堆栈是一种数据结构,它可用于在程序中管理函数调用、表达式求值、任务管理和许多其他用途。Python 核心语言并没有提供内置的堆栈数据类型,但是,使用 Python 的列表就可以轻松地实现堆栈。在本文中,我们将探讨堆栈的基本概念,以及 Python 中堆栈的实现和应用。

堆栈的基本概念

堆栈是一个后进先出(LIFO)数据结构,这意味着最后一个插入堆栈的元素最先移出堆栈。堆栈有两个主要操作:

  • push:将一个元素添加到堆栈的顶部。

  • pop:从堆栈的顶部移除最后添加的元素。

堆栈还具有许多其他操作,如查看堆栈的顶部元素(但不移除它)和确定堆栈是否为空。

在 Python 中实现堆栈

Python 中的列表可以用于实现堆栈。例如,以下代码创建一个空的堆栈:

stack = []

要将元素推入堆栈,可以使用 append() 方法,如下所示:

stack.append(1)
stack.append(2)
stack.append(3)

这将在堆栈的顶部添加三个元素。现在,如果使用 pop() 方法,可以按逆序从堆栈中移除元素:

stack.pop()  # 输出 3
stack.pop()  # 输出 2
stack.pop()  # 输出 1

在上面的代码中,pop() 方法从堆栈的顶部移除每个元素,并将其返回。最后一个 pop() 的调用将从堆栈中移除最后添加的元素(即 $3$)并将其返回。stack 现在为空列表,因为它不包含任何元素。

堆栈的应用

下面是堆栈在 Python 中的几个常见应用:

1. 表达式求值

堆栈可用于求解表达式并评估其值。例如,考虑以下中缀表达式:

$$ 2 + 3 \times 4 - 5 $$

在求解此表达式时,可以使用两个堆栈:一个用于操作符,另一个用于操作数。从左到右扫描表达式,将所有操作数推入操作数堆栈。当遇到运算符时,将其与操作符堆栈的顶部元素进行比较。如果新运算符的优先级低于或等于堆栈顶部运算符的优先级,则从操作数堆栈中弹出两个操作数,并使用堆栈顶部的运算符对它们进行计算。然后将计算结果推入操作数堆栈中。例如,以下代码使用堆栈求解上述表达式:

def evaluate_expression(expression):
  operators = []
  operands = []
  for token in expression.split():
    if token.isdigit():
      operands.append(int(token))
    else:
      while operators and precedence(operators[-1]) >= precedence(token):
        apply_operator(operators, operands)
      operators.append(token)
  while operators:
    apply_operator(operators, operands)
  return operands[0]

def precedence(operator):
  if operator in '+-':
    return 1
  elif operator in '*/':
    return 2
  else:
    return 0

def apply_operator(operators, operands):
  operator = operators.pop()
  right_operand = operands.pop()
  left_operand = operands.pop()
  result = evaluate(left_operand, operator, right_operand)
  operands.append(result)

def evaluate(left_operand, operator, right_operand):
  if operator == '+':
    return left_operand + right_operand
  elif operator == '-':
    return left_operand - right_operand
  elif operator == '*':
    return left_operand * right_operand
  else:
    return left_operand / right_operand

expression = "2 + 3 * 4 - 5"
result = evaluate_expression(expression)
print(result)  # 输出 9
2. 函数调用堆栈

在 Python 中,每次调用函数时,都会创建一个新的堆栈帧,并将其推入调用堆栈中。当函数返回时,堆栈帧将从调用堆栈中弹出,并将控制返回到调用方。例如,以下代码定义了两个函数 foo()bar(),并演示了函数调用堆栈:

def foo():
  print("foo() 开始")
  bar()
  print("foo() 结束")

def bar():
  print("bar() 开始")
  print("bar() 结束")

foo()

输出结果如下:

foo() 开始
bar() 开始
bar() 结束
foo() 结束

在此示例中,调用 foo() 会创建一个新的堆栈帧,并将其推入调用堆栈中。在 foo() 中调用 bar() 会创建另一个堆栈帧,并将其推入调用堆栈的顶部。当 bar() 返回时,它的堆栈帧将从调用堆栈中弹出,并将控制返回到 foo()。最后,当 foo() 返回时,它的堆栈帧也将从调用堆栈中弹出,并将控制返回到脚本的主体。

3. 管理撤销和重做操作

堆栈可用于管理用户的撤销和重做操作。例如,用户对文档进行编辑时,可以将每个操作存储在堆栈中以便撤销或重做。以下代码演示了如何使用堆栈实现简单的撤销和重做功能:

class Editor:
  def __init__(self):
    self.document = ""
    self.command_stack = []
    self.undo_stack = []

  def insert(self, text):
    self.document += text
    self.command_stack.append(('insert', text))
    self.undo_stack.clear()

  def delete(self):
    if not self.document:
      return
    deleted_char = self.document[-1]
    self.document = self.document[:-1]
    self.command_stack.append(('delete', deleted_char))
    self.undo_stack.clear()

  def undo(self):
    if not self.command_stack:
      return
    last_command = self.command_stack.pop()
    if last_command[0] == 'insert':
      self.document = self.document[:-len(last_command[1])]
    else:
      self.document += last_command[1]
    self.undo_stack.append(last_command)

  def redo(self):
    if not self.undo_stack:
      return
    last_undo = self.undo_stack.pop()
    if last_undo[0] == 'insert':
      self.document += last_undo[1]
    else:
      self.document = self.document[:-len(last_undo[1])]
    self.command_stack.append(last_undo)

editor = Editor()
editor.insert("Hello ")
editor.insert("world!")
print(editor.document)  # 输出 "Hello world!"

editor.delete()
print(editor.document)  # 输出 "Hello "

editor.undo()
print(editor.document)  # 输出 "Hello world!"

editor.redo()
print(editor.document)  # 输出 "Hello "

在此示例中,Editor 类封装了文档及其编辑操作。insert() 方法向文档添加文本,并将新的 ('insert', text) 命令推入 command_stackdelete() 方法从文档中删除最后一个字符,并将新的 ('delete', deleted_char) 命令推入 command_stackundo() 方法从 command_stack 弹出最后一个命令,并反转其影响。具体来说,如果该命令是 ('insert', text),则将文档中的文本删除以撤消命令。如果命令是 ('delete', deleted_char),则向文档中添加字符以撤消命令。每个撤销操作将已撤销的命令推入 undo_stackredo() 方法从 undo_stack 弹出最后一个命令,并重新执行它。具体来说,如果该命令是 ('insert', text),则将文本添加到文档中。如果命令是 ('delete', deleted_char),则从文档中删除字符。每个重做操作将已重做的命令推入 command_stack