python实现栈

python-栈的实现
栈(Stack)的定义:只允许在一端进行插入或者删除操作的线性表。
栈顶(Top):线性表允许插入和删除的那一端。
栈底(Bottom):固定的,不允许进行插入和删除的那一端。
空栈:不含任何元素的空表。

这里借用一个百度百科的图片展示入栈和出栈的过程:
在这里插入图片描述
栈是后入先出(LIFO,last-in-first-out)的数据结构,假设栈中原始数据为(2,7,1)
该图展示了8和2依次入栈(Push())
以及(2,8,1)依次出栈(Pop())的过程。
栈的基本操作:
IniStack():初始化一个空栈
isempty():判空
isfull():判满
Push():若栈未满,则入栈
Pop():若栈非空,则出栈
GetTop():获取栈顶元素

顺序栈的实现:

# 后进先出
class myStack():
    def __init__(self,size):
        self.size=size  #栈的大小
        self.stack=[]	#定义一个空栈
        self.top=-1		#指示栈的存储情况,初始为-1,表示空栈,每入栈一个元素,top增加1,每出栈一个元素,top减少1

    def push(self, x): # 入栈之前检查栈是否已满
        if self.isfull():
            print("stack is full")
            return False
        else:
            self.stack.append(x)
            self.top = self.top + 1
            return True

    def pop(self):# 出栈之前检查栈是否为空
        if self.isempty():
            print("stack is empty")
            return False
        else:
            self.top = self.top - 1
            self.stack.pop()
            return True
    def gettop(self):
        if self.top!=-1:
            return self.stack[self.top]
    def isfull(self):
        return self.top+1 == self.size
    def isempty(self):
        return self.top == '-1'
    def showStack(self):
        print(self.stack)


s=myStack(10)
for i in range(10):
    s.push(i)
s.showStack()
print(s.gettop())

s.push("100")
for i in range(6):
    s.pop()
s.showStack()


输出为:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
9
stack is full
[0, 1, 2, 3]

需要注意的地方:
1)入栈的时候:元素先入栈,top再增1;出栈时:top先减1,元素后出栈
2)top初值为-1表示空栈,top+1==size表示满栈
在这里插入图片描述共享栈:

在这里插入图片描述
利用栈底位置相对不变的特性,可以让两个顺序栈共享一个一维空间,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸。
两个栈的栈顶指针都指向栈顶元素,top0=-1时0号栈为空,top1=maxSize时1号栈为空,仅当两个栈顶相邻时栈满:top1-top0==1
入栈时,top0先加1再赋值;top1先减1再赋值

class SharedStack:
    def __init__(self, size):
        self.size = size
        self.array = [None] * size  # 初始化共享空间
        self.top1 = -1  # 第一个栈的栈顶位置
        self.top2 = size  # 第二个栈的栈顶位置

    def push1(self, value):
        if self.top1 < self.top2 - 1:  # 检查是否还有空间可用
            self.top1 += 1
            self.array[self.top1] = value
        else:
            print("Stack 1 overflow")

    def push2(self, value):
        if self.top1 < self.top2 - 1:  # 检查是否还有空间可用
            self.top2 -= 1
            self.array[self.top2] = value
        else:
            print("Stack 2 overflow")

    def pop1(self):
        if self.top1 >= 0:  # 检查第一个栈是否为空
            value = self.array[self.top1]
            self.top1 -= 1
            return value
        else:
            print("Stack 1 underflow")
            return None

    def pop2(self):
        if self.top2 < self.size:  # 检查第二个栈是否为空
            value = self.array[self.top2]
            self.top2 += 1
            return value
        else:
            print("Stack 2 underflow")
            return None

# 创建一个大小为10的共享栈
shared_stack = SharedStack(10)

# 向第一个栈压入数据
shared_stack.push1(1)
shared_stack.push1(2)
shared_stack.push1(3)

# 向第二个栈压入数据
shared_stack.push2(4)
shared_stack.push2(5)

# 从第一个栈弹出数据
print(shared_stack.pop1())  # 输出:3

# 从第二个栈弹出数据
print(shared_stack.pop2())  # 输出:5

首先,创建一个共享栈的类 SharedStack,在初始化方法中,指定了共享空间的大小,并创建了一个列表 array来存储共享空间的数据。 通过两个指针 top1 和 top2 分别表示两个栈的栈顶位置。初始时,第一个栈的栈顶 top1 设置为-1,第二个栈的栈顶 top2 设置为共享空间的大小。 实现 push1 和 push2 方法来向两个栈中压入数据。在压入数据时,我们需要检查栈是否已满,即 top1 是否小于 top2 - 1,如果满了则输出溢出信息。 实现pop1 和 pop2 方法来从两个栈中弹出数据。在弹出数据时,我们需要检查栈是否为空,即 top1 是否大于等于 0 或者 top2是否小于共享空间的大小,如果为空则输出下溢信息。
最后,我们创建一个大小为10的共享栈实例,向两个栈分别压入数据,然后从两个栈分别弹出数据,以验证共享栈的功能。

链栈:
采用链式存储结构的栈,不存在栈满溢出的情况,便于节点的插入和删除,通常用单链表实现,并规定所有的操作都是在表头进行的。
下图的链栈没有头结点,Lhead指向栈顶元素。
在这里插入图片描述

class ListNode:
    def __init__(self, value=0, next=None):
        self.value = value
        self.next = next

class LinkedStack:
    def __init__(self):
        self.top = None  # 栈顶指针,初始时指向空

    def push(self, value):
        new_node = ListNode(value)  # 创建一个新节点
        new_node.next = self.top     # 将新节点的next指针指向当前栈顶节点
        self.top = new_node          # 更新栈顶指针,指向新节点

    def pop(self):
        if self.top is None:
            raise Exception("Stack is empty")  # 如果栈为空,则抛出异常
        value = self.top.value        # 获取栈顶节点的值
        self.top = self.top.next     # 将栈顶指针指向下一个节点
        return value                 # 返回弹出的值

    def is_empty(self):
        return self.top is None      # 如果栈顶指针为空,则栈为空

    def peek(self):
        if self.top is None:
            raise Exception("Stack is empty")  # 如果栈为空,则抛出异常
        return self.top.value        # 返回栈顶节点的值

# 创建一个链栈实例
stack = LinkedStack()

# 将元素依次压入栈中
stack.push(1)
stack.push(2)
stack.push(3)

# 弹出栈顶元素并打印
print("弹出栈顶元素:", stack.pop())

# 打印当前栈顶元素
print("当前栈顶元素:", stack.peek())

# 判断栈是否为空
print("栈是否为空:", stack.is_empty())

定义一个 ListNode 类来表示链栈的节点,每个节点包含一个 value 值和一个 next 指针指向下一个节点。 定义一个 LinkedStack 类来实现链栈。其中 top 指针指向栈顶节点,初始时为空。 push方法用于向栈中压入元素,每次压入元素时,创建一个新节点,将新节点的 next 指针指向当前栈顶节点,然后更新 top 指针,使其指向新节点。
pop 方法用于弹出栈顶元素,首先检查栈是否为空,然后获取栈顶节点的值,并将 top 指针指向下一个节点,最后返回弹出的值。
is_empty 方法用于判断栈是否为空,只需判断 top 指针是否为空即可。 peek 方法用于获取栈顶元素的值,首先检查栈是否为空,然后返回栈顶节点的值。
通过以上实现,我们完成了链栈的基本操作,并且可以对链栈进行压栈、弹栈、查看栈顶元素和判断栈是否为空等操作。

  • 10
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值