geekdoc-python-zh/docs/py4b/implement-stack-in-python.md

6.4 KiB
Raw Permalink Blame History

在 Python 中实现堆栈

原文:https://www.pythonforbeginners.com/data-types/implement-stack-in-python

栈是一种数据结构,它遵循后进先出(LIFO)的顺序来访问元素。在堆栈中,我们只能访问最近添加的元素。堆栈在表达式处理、回溯和函数调用等应用中有很多用途。在本文中,我们将尝试用 python 实现带链表的堆栈数据结构。

使用链表在 Python 中实现堆栈

链表是一种线性数据结构,其中每个数据对象指向另一个对象。为了用链表实现一个堆栈,我们将不得不执行插入和删除,以及从链表中删除元素,这样它将花费恒定的时间。只有当我们在链表的开头插入和删除元素时,这才是可能的。

为了在 python 中实现带链表的堆栈,我们将首先定义一个 node 对象,它将包含当前元素,并使用引用 next 指向插入它之前的节点。在 python 中,该节点可以按如下方式实现。

class Node:
    def __init__(self,data,size):
        self.data=data
        self.next=None

当我们用链表实现一个堆栈时,它将有一个名为 top 的元素,这个元素将引用链表中最近插入的元素。所有其他元素都可以通过它来访问。我们可以用 python 实现一个空栈top 初始化为 NonestackSize 初始化为 0如下所示。

class Stack:
    def __init__(self):
        self.top=None
        self.stackSize=0

在 Python 中实现栈中的推送操作

当我们将一个元素插入到堆栈中时,这个操作叫做 push 操作。为了在链表的帮助下实现栈中的 push 操作,对于每一次插入,我们将在链表的开头添加要插入的元素。这样,最近的元素将总是在链表的开始。然后,我们将堆栈的顶部元素指向链表的开头,并将 stackSize 递增 1。可以使用 python 中的链表实现推送操作,如下所示。

 def push(self,data):
        temp=Node(data)
        if self.top is None:
            self.top=temp
            self.stackSize= self.stackSize+1
        else:
            temp.next=self.top
            self.top=temp
            self.stackSize=self.stackSize+1

用 Python 实现堆栈中的弹出操作

当我们从堆栈中取出一个元素时,这个操作被称为弹出操作。要从堆栈中取出的元素是最近添加到堆栈中的元素。正如我们所知,在推送操作中,我们将最近的元素添加到堆栈顶部指向的链表的开头,因此我们将删除顶部指向的元素,并将顶部指向下一个最近的元素。在执行弹出操作之前,我们将检查堆栈是否为空。如果堆栈为空,即 top 指向 None我们将使用 python try except 引发一个异常,并显示堆栈为空的消息。我们可以如下实现 pop 操作。

 def pop(self):
        try:
            if self.top == None:
                raise Exception("Stack is Empty")
            else:
                temp=self.top
                self.top=self.top.next
                tempdata=temp.data
                self.stackSize= self.stackSize-1
                del temp
                return tempdata
        except Exception as e:
            print(str(e))

如何访问栈顶元素

由于栈顶的元素被 top 引用,我们只需返回 top 指向的节点中的数据。它可以按如下方式实现。

def top_element(self):
        try:
            if self.top == None:
                raise Exception("Stack is Empty")
            else:
                return self.top.data
        except Exception as e:
            print(str(e))

获取堆栈的大小

因为我们在 stackSize 变量中保留了当前的堆栈大小,所以我们只需返回 stackSize 变量 top 中的值。这可以如下进行。

def size(self):
        return self.stackSize

检查堆栈是否为空

元素 top 指的是堆栈中最近的元素。如果堆栈中没有元素top 将指向 None。因此要检查堆栈是否为空我们只需检查 top 是否指向 None 或者 stackSize 变量的值是否为 0。我们可以实现 isEmpty()方法来检查堆栈是否为空,如下所示。

def isEmpty(self):
        if self.stackSize==0:
            return True
        else:
            return False

使用 python 中的链表实现堆栈的完整工作代码如下。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Apr 25 00:28:19 2021

@author: aditya1117
"""

class Node:
    def __init__(self,data):
        self.data=data
        self.next=None
class Stack:
    def __init__(self):
        self.top=None
        self.stackSize=0
    def push(self,data):
        temp=Node(data)
        if self.top is None:
            self.top=temp
            self.stackSize= self.stackSize+1
        else:
            temp.next=self.top
            self.top=temp
            self.stackSize=self.stackSize+1
    def pop(self):
        try:
            if self.top == None:
                raise Exception("Stack is Empty")
            else:
                temp=self.top
                self.top=self.top.next
                tempdata=temp.data
                self.stackSize= self.stackSize-1
                del temp
                return tempdata
        except Exception as e:
            print(str(e))
    def isEmpty(self):
        if self.stackSize==0:
            return True
        else:
            return False
    def size(self):
        return self.stackSize
    def top_element(self):
        try:
            if self.top == None:
                raise Exception("Stack is Empty")
            else:
                return self.top.data
        except Exception as e:
            print(str(e))
s=Stack()
s.push(1)
print(s.size())

s.push(2)
print(s.size())

print(s.pop())
print(s.size())
print(s.pop())
print(s.stackSize)

print(s.top_element())
print(s.isEmpty())

输出:

1
2
2
1
1
0
Stack is Empty
None
True

结论

在本文中,我们使用 python 中的链表实现了 stack 及其所有操作。为了更深入地了解它,并理解 stack 与内置数据结构(如 python dictionary 、list 和 set)有何不同,复制上面示例中给出的完整代码,并试验其中的操作。请继续关注更多内容丰富的文章。