python中使用Del

时间:2018-05-22 22:33:14

标签: python doubly-linked-list

我正在分析删除节点的双向链表功能。但是我有点困惑。

def remove( self, p ) :
        tmp = p.prev
        p.prev.next = p.next
        p.prev = tmp

为什么有tmp = p.prev和p.prev = tmp。这些额外线路的目的是什么?最后,为什么没有删除节点" del"?不应该是" del p"在代码的最后?

谢谢!

1 个答案:

答案 0 :(得分:3)

首先,如果这是整个功能,那就错了,这可能是你理解它的原因之一。

要从双向链表中删除节点,您需要做三件事:

  1. 使前一个节点指向下一个节点,而不是p节点。
  2. 使下一个节点返回上一个节点,而不是当前节点。
  3. 删除当前节点。
  4. 因为Python是垃圾收集的,所以 1 步骤3会自动发生。 2

    步骤1由​​p.prev.next = p.next处理。

    但是第2步不会发生在任何地方。 p.next.prev仍指向p,而不是p.prev。这意味着如果您向前走列表,p将不会成为其中的一部分 - 但如果您向后走,它。因此p实际上并未删除。

    与此同时,tmp = p.prev后跟p.prev = tmp并没有做任何有用的事情。 3 而且,无论尝试做什么,你几乎都是在Python中永远不需要tmp;您可以仅使用x, y = y, x代替tmp = x; x = y; y = tmp来交换值。

    所以,你实际上想要的是:

    def remove(self, p):
        p.prev.next = p.next
        p.next.prev = p.prev
    

    <子> 1。 CPython,你可能正在使用的Python的参考解释器,通过自动引用计数进行垃圾收集,偶尔运行一个循环断路器。这是否算作“真正的”垃圾收集是一个很好的圣战争论,但这并不重要。

    <子> 2。您只需要删除对象的所有引用,它就会变成垃圾并自动清理。因此,您需要将下一个和上一个节点的引用移除到您已经在进行的p。你需要让p消失,但你不需要del p - 它是一个局部变量;当你从函数返回时它会消失。之后,由remove的来电者决定;如果他们没有保留对节点的任何引用,那么该节点就是垃圾。

    <子> 3。如果我们暂时为p.prev分配了不同的值并希望在函数结束时恢复它,可以做一些有用的事情。但这并没有发生在这里,我不认为编写此代码的人有意这样的事情;我认为他们正试图进行某种交换。