在 python 中使用链表实现堆栈。 pop 方法的问题和关于可变性的问题

Posted

技术标签:

【中文标题】在 python 中使用链表实现堆栈。 pop 方法的问题和关于可变性的问题【英文标题】:Implementing a stack using a linked list in python. Issues with pop method and questions about mutability 【发布时间】:2017-05-23 04:43:08 【问题描述】:

我正在尝试使用仅基于节点类的链表来实现堆栈。我的班级的 pop 方法出现了一些问题,似乎没有表现出可变性。当我使用 pop 类方法时,它会正确返回堆栈的顶部,但无法更新堆栈。

x=stack_linked(1)
x=x.insert(2)
x=x.insert(3)
x.print() # This is correct and prints 3,2,1
print(x.pop()) # This is correct and prints 3, but doesn't actually modify my list
x.print() # This prints 3,2,1

为什么 self 不可变?另外,如何在不完全炸毁它或为其创建包装器的情况下修改我的类?这是我的课。

class stack_linked(object):
    def __init__(self,data):
     self.data=data
     self.next=None

    def insert(self,front):
     front=stack_linked(front)
     front.next=self
     return front

    def peek(self):
     if self==None:
        return None
     else   
        return self.data

    def pop(self):
     front=self
     self=self.next # some sort of issue here
     return front


    def print(self):
     x=self
     if x==None:
        print("Empty")
     else:
        print(x.data)
     while x.next !=None:
        x=x.next
        print(x.data) 

【问题讨论】:

在实例方法中分配给self 不会导致整个实例被替换。 那么,我该如何重做 pop 方法呢? 这也是可变性的问题吗?还是不相关? pop 应该返回数据,而不是节点.. 不相关,参见例如nedbatchelder.com/text/names.html 【参考方案1】:

你有点受限于只有节点和前向链接,但可以通过使第一个节点包含第二个节点来实现 pop(-first):

class stack_linked(object):
    def __init__(self, data):
        self.data = data
        self.next = None

    def pop(self):
        data = self.data
        nxt = self.next
        if nxt is None:
            self.data = self.next = None
        else:
            self.data = nxt.data
            self.next = nxt.next
            nxt.next = None
        return data

【讨论】:

为什么还要设置nxt.next=None? nxt.next = None 可以打破任何循环,以便垃圾收集器更轻松。在语义上它也是正确的,因为 nxt 对象不再存在,因此不应指向活动对象。

以上是关于在 python 中使用链表实现堆栈。 pop 方法的问题和关于可变性的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何从链表中反转堆栈?

在 Python 中使用链表实现堆栈

如何用Python实现堆栈和队列详细讲解

c语言中(不是C++)具体实现堆栈代码,后进先出原理我懂!

堆栈 - 为啥是 PUSH 和 POP?

基于C语言堆栈push,pop,destroystack,isEmpty,isFull实现