我正在分析删除节点的双向链表功能。但是我有点困惑。
def remove( self, p ) :
tmp = p.prev
p.prev.next = p.next
p.prev = tmp
为什么有tmp = p.prev和p.prev = tmp。这些额外线路的目的是什么?最后,为什么没有删除节点" del"?不应该是" del p"在代码的最后?
谢谢!
答案 0 :(得分:3)
首先,如果这是整个功能,那就错了,这可能是你理解它的原因之一。
要从双向链表中删除节点,您需要做三件事:
p
节点。因为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
分配了不同的值并希望在函数结束时恢复它,可以做一些有用的事情。但这并没有发生在这里,我不认为编写此代码的人有意这样的事情;我认为他们正试图进行某种交换。