【问题标题】:How to remove a node from a linked list in Python easily?如何轻松地从 Python 中的链表中删除节点?
【发布时间】:2020-12-15 13:07:08
【问题描述】:

我很难尝试在队列类中创建一个函数来删除某个节点,参数是节点的值。


class LinkedQ:

    def __init__(self):
        self._first = None
        self._last = None
    
    def enqueue(self,x):
        ny = Node(x)
        if self._first == None:
            self._first = ny
            self._last = ny
        else:
            self._last.next = ny
            self._last = ny


    def remove(self,x):
        current_node = self._first

        while x != current_node.data: #Node(x):
            last_node = current_node
            current_node = current_node.next
            if current_node == Node(x):
                last_node.next = current_node.next
                return


    def display(self):
        if self._first == None:
            return None
        else:
            elements = []
            current_node = self._first
            elements.append(current_node.data)
            while current_node.next != None:
                current_node = current_node.next
                elements.append(current_node.data)
            
            print(elements)


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



p = LinkedQ()

p.enqueue(1)
p.enqueue(2)
p.enqueue(3)
p.enqueue(4)
p.enqueue(5)

p.display()


p.remove(3)
p.display()



所以我似乎无法使用函数def remove(self,x)。因为现在我没有收到错误消息,但使用def display(self): 的输出仍然相同:

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]

表示所选节点尚未删除。 有人可以告诉我我做错了什么吗?而我该如何解决呢? 如您所见,我试图通过将前一个节点的指针更改为指向位于我们当前节点之后的节点来解决它,使其消失当没有任何东西指向它时。这就是我们需要解决的方法。

PS。代码中还有其他函数,例如 enqueue() isEmpty(),但在本例中这些函数不相关,它们现在可以正常工作。

【问题讨论】:

  • 您的 enqueue 方法是否创建 Node 对象?因为目前您正在排队整数而不是 Node 对象。此外,您的删除方法似乎没有正确缩进。
  • 实际查看您的入队方法可能是相关的。它在创建 Node 对象时是否指定了下一个参数?还是 next 总是保留默认的 None 值?
  • 您好,它的缩进是正确的,但是当我在这里复制和粘贴时显然搞砸了。是的,它确实创建了 Node 对象,如您在此处看到的:imgur.com/vGt5mjs 并且在上面的代码中,我还编辑了包含 enqueue()

标签: python class linked-list


【解决方案1】:

其他人已经证明罪魁祸首是if current_node == Node(x):这行,应该是if current_node.data == x:,除非你想在Node中定义一个__eq__成员函数

但恕我直言,这不是唯一的问题:LinkedQ 作为指向列表头部和尾部的指针。如果删除队列的第一个或最后一个元素,则必须重置相应的指针(或者两者都是列表变为空)。

【讨论】:

  • 感谢您的帮助和对我的问题的进一步评论。我添加了一个 if 语句以确保删除函数适用于列表中的第一个元素。我必须修改它以适用于列表中也不存在的给定 x。
  • 我的回答没有解决这个问题,所以一定要看看这个!
【解决方案2】:

您的 while 循环在能够删除正确的值之前中断。如果您在 while 循环中放置一个 print 来打印 current_node.data 的值,您会看到您只进入了 Node(1) 和 Node(2) 的循环。在 Node(2) 之后,while 循环条件中断。

你可能应该做更多这样的事情:

while True:
    last_node = current_node
    current_node = current_node.next
    if current_node.data == x:
        last_node.next = current_node.next
        return

【讨论】:

  • 非常感谢您的帮助!我了解您所做的更改,但是我不完全确定为什么 if current_node.data == x: 有效但 if current_node == Node(x) 无效,您的比较值,而我的比较节点。我想你不能那样做吗?
  • Node(x) 创建一个新的 Node 对象。它们有不同的内存地址。使用x = Node(1); y = Node(1); print(id(x)); print(id(y)); print(x == y) 对此进行测试。您会看到它们不是相同的内存地址,因此相等运算符不起作用。如果你想让相等运算符工作,你必须定义一个 eq 方法!
  • 这里是实现对象相等的一个很好的解释:stackoverflow.com/questions/1227121/…
【解决方案3】:

您的删除方法中有一个错误:

def remove(self,x):
    current_node = self._first
    
    while current_node and x != current_node.data:
        last_node = current_node
        current_node = current_node.next
        if current_node.data == x: #<==== Here
            last_node.next = current_node.next
            return

【讨论】:

    猜你喜欢
    • 2014-09-03
    • 1970-01-01
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 2013-01-08
    相关资源
    最近更新 更多