当前位置: 首页 > news >正文

玩转python:掌握Python数据结构之栈Stack

栈(Stack)是计算机科学中一种非常基础且重要的数据结构。它的特点是后进先出(LIFO,Last In First Out),就像我们生活中叠盘子一样,最后放上去的盘子总是最先被拿走。本文将用通俗易懂的语言和丰富的案例,带你轻松掌握栈的概念、实现和应用。


什么是栈?

栈是一种线性数据结构,它只允许在一端进行数据的插入和删除操作。这一端被称为栈顶(Top),另一端被称为栈底(Bottom)。栈的操作主要有两种:

  1. 入栈(Push):将数据放入栈顶。
  2. 出栈(Pop):从栈顶取出数据。

栈的典型特点是后进先出,也就是说,最后入栈的数据会最先出栈。


生活中的栈

为了更好地理解栈,我们可以从生活中找到许多栈的例子:

  1. 叠盘子

    • 当你洗完盘子后,会把盘子一个一个叠起来。最后放上去的盘子总是最先被拿走。
    • 这就是栈的“后进先出”特性。
  2. 浏览器的返回按钮

    • 当你浏览网页时,每次点击一个新链接,浏览器都会将当前页面压入栈中。
    • 当你点击返回按钮时,浏览器会从栈顶弹出上一个页面。
    • 这就是栈的“入栈”和“出栈”操作。
  3. 撤销操作

    • 在文本编辑器中,每次编辑操作(如输入文字、删除文字)都会被记录到栈中。
    • 当你按下撤销键时,编辑器会从栈顶弹出最近的操作并撤销。
    • 这就是栈的“后进先出”特性。

栈的实现

在Python中,栈可以通过列表(List)或链表(Linked List)来实现。下面我们用列表来实现一个简单的栈。

1. 使用列表实现栈

class Stack:
    def __init__(self):
        self.items = []  # 用列表存储栈中的数据

    # 入栈操作
    def push(self, item):
        self.items.append(item)  # 将数据添加到列表末尾(栈顶)

    # 出栈操作
    def pop(self):
        if not self.is_empty():  # 如果栈不为空
            return self.items.pop()  # 弹出列表末尾的数据(栈顶)
        return None  # 如果栈为空,返回None

    # 查看栈顶元素
    def peek(self):
        if not self.is_empty():  # 如果栈不为空
            return self.items[-1]  # 返回列表末尾的数据(栈顶)
        return None  # 如果栈为空,返回None

    # 判断栈是否为空
    def is_empty(self):
        return len(self.items) == 0  # 如果列表为空,栈为空

    # 返回栈的大小
    def size(self):
        return len(self.items)  # 返回列表的长度

    # 打印栈的内容
    def print_stack(self):
        print("栈顶 ->", self.items, "<- 栈底")

# 使用栈
stack = Stack()
stack.push(1)  # 入栈
stack.push(2)
stack.push(3)
stack.print_stack()  # 输出: 栈顶 -> [1, 2, 3] <- 栈底
print(stack.pop())  # 输出: 3(出栈)
stack.print_stack()  # 输出: 栈顶 -> [1, 2] <- 栈底
print(stack.peek())  # 输出: 2(查看栈顶元素)

栈的应用案例

栈在计算机科学中有广泛的应用,以下是几个常见的案例:

1. 浏览器的返回功能

浏览器的返回功能可以用栈来实现。每次访问一个新页面时,将当前页面压入栈中;点击返回按钮时,从栈顶弹出上一个页面。

class Browser:
    def __init__(self):
        self.back_stack = Stack()  # 后退栈
        self.forward_stack = Stack()  # 前进栈

    # 访问新页面
    def visit(self, page):
        self.back_stack.push(page)  # 将当前页面压入后退栈
        self.forward_stack = Stack()  # 清空前进栈
        print(f"访问页面: {page}")

    # 后退
    def back(self):
        if self.back_stack.size() > 1:  # 如果后退栈中有多个页面
            current_page = self.back_stack.pop()  # 弹出当前页面
            self.forward_stack.push(current_page)  # 将当前页面压入前进栈
            previous_page = self.back_stack.peek()  # 查看上一个页面
            print(f"后退到页面: {previous_page}")
        else:
            print("无法后退")

    # 前进
    def forward(self):
        if not self.forward_stack.is_empty():  # 如果前进栈不为空
            next_page = self.forward_stack.pop()  # 弹出下一个页面
            self.back_stack.push(next_page)  # 将下一个页面压入后退栈
            print(f"前进到页面: {next_page}")
        else:
            print("无法前进")

# 使用浏览器
browser = Browser()
browser.visit("首页")
browser.visit("关于我们")
browser.visit("联系我们")
browser.back()  # 输出: 后退到页面: 关于我们
browser.forward()  # 输出: 前进到页面: 联系我们

2. 文本编辑器的撤销功能

文本编辑器的撤销功能可以用栈来实现。每次编辑操作(如输入文字、删除文字)都会被记录到栈中;按下撤销键时,从栈顶弹出最近的操作并撤销。

class TextEditor:
    def __init__(self):
        self.content = ""  # 当前文本内容
        self.undo_stack = Stack()  # 撤销栈

    # 输入文字
    def type(self, text):
        self.undo_stack.push(self.content)  # 将当前内容压入撤销栈
        self.content += text  # 更新内容
        print(f"当前内容: {self.content}")

    # 撤销
    def undo(self):
        if not self.undo_stack.is_empty():  # 如果撤销栈不为空
            previous_content = self.undo_stack.pop()  # 弹出上一个内容
            self.content = previous_content  # 恢复内容
            print(f"撤销后内容: {self.content}")
        else:
            print("无法撤销")

# 使用文本编辑器
editor = TextEditor()
editor.type("Hello")  # 输出: 当前内容: Hello
editor.type(" World")  # 输出: 当前内容: Hello World
editor.undo()  # 输出: 撤销后内容: Hello

3. 括号匹配检查

栈可以用来检查表达式中的括号是否匹配。例如,检查 ((a + b) * (c - d)) 中的括号是否正确配对。

def is_balanced(expression):
    stack = Stack()  # 创建一个栈
    for char in expression:
        if char == "(":  # 如果是左括号,压入栈
            stack.push(char)
        elif char == ")":  # 如果是右括号
            if stack.is_empty():  # 如果栈为空,说明没有匹配的左括号
                return False
            stack.pop()  # 弹出栈顶的左括号
    return stack.is_empty()  # 如果栈为空,说明括号匹配

# 检查括号是否匹配
print(is_balanced("((a + b) * (c - d))"))  # 输出: False
print(is_balanced("((a + b) * (c - d)"))  # 输出: True

4. 计算后缀表达式

栈可以用来计算后缀表达式(也称为逆波兰表达式)。例如,计算 3 4 + 5 * 的值。

def evaluate_postfix(expression):
    stack = Stack()  # 创建一个栈
    for token in expression.split():  # 将表达式按空格分割
        if token.isdigit():  # 如果是数字,压入栈
            stack.push(int(token))
        else:  # 如果是运算符
            operand2 = stack.pop()  # 弹出第二个操作数
            operand1 = stack.pop()  # 弹出第一个操作数
            if token == "+":
                stack.push(operand1 + operand2)
            elif token == "-":
                stack.push(operand1 - operand2)
            elif token == "*":
                stack.push(operand1 * operand2)
            elif token == "/":
                stack.push(operand1 / operand2)
    return stack.pop()  # 返回最终结果

# 计算后缀表达式
print(evaluate_postfix("3 4 + 5 *"))  # 输出: 35

总结

栈是一种简单但功能强大的数据结构,它的“后进先出”特性在计算机科学中有广泛的应用。通过本文的学习,你应该已经掌握了栈的基本概念、实现方法以及常见应用场景。无论是浏览器的返回功能、文本编辑器的撤销功能,还是括号匹配检查和后缀表达式计算,栈都能提供高效的解决方案。

希望本文能帮助你更好地理解栈,并在实际编程中灵活运用!

相关文章:

  • SPI学习笔记
  • 数电笔记——第二章 逻辑代数基础(二)
  • seacmsv9报错注入管理员密码+orderby+limit
  • Django下防御Race Condition
  • 【时间序列】因果推断:从时序数据中探寻“因”与“果”
  • GStreamer —— 2.9、Windows下Qt加载GStreamer库后运行 - “教程9:媒体信息收集“(附:完整源码)
  • WebSocket(WS)协议系列(四)SSL/TLS协议
  • flask学习3-深入
  • ConcurrentHashMap底层原理
  • RK3588部署YOLOv8(2):OpenCV和RGA实现模型前处理对比
  • 网络安全需要报班学习吗?
  • 重塑未来:生成式AI如何重构企业数据基因?三大技术重构的生死局
  • Paper Reading | AI 数据库融合经典论文回顾
  • ‌HTTP/1.0、HTTP/2.0和HTTP/3.0的区别
  • Pytest自动化框架
  • 深入理解 JavaScript 执行上下文
  • 【LTSPCIE】D触发器的搜索和使用
  • K8S高可用Web应用部署方案
  • Docker网络设置
  • java遍历
  • 网站建设实训的目的/如何做网络销售平台
  • 个人网站建设流程/seo优化的内容有哪些
  • 广州知名网站建设后台管理便捷/搜索引擎营销的主要方法
  • java做网站与php做网站/已备案域名购买平台
  • 一家专门做衣服的网站/百度关键词seo外包
  • wordpress简约商城/苏州整站优化