python - python中使用Del的双向链表
问题描述
我正在分析一个删除节点的双向链表函数。但是我有点困惑。
def remove( self, p ) :
tmp = p.prev
p.prev.next = p.next
p.prev = tmp
为什么会有 tmp = p.prev 和 p.prev = tmp。这些额外行的目的是什么?最后,为什么没有用“del”删除节点?代码末尾不应该是“del p”吗?
谢谢!
解决方案
首先,如果这是整个函数,那就错了,这可能是您无法理解它的部分原因。
要从双向链表中删除一个节点,你需要做三件事:
- 使前一个节点指向下一个节点,而不是该
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
你可以用 just而不是交换值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
但这并没有发生在这里,而且我认为编写此代码的人没有这样的意图。我认为他们试图进行某种交换。
推荐阅读
- python - 包含数组 float32 元素的字典
- javafx - 以德语显示菜单快捷方式
- r - 合并两个数据帧时识别行中的更改
- java - Glassfish 服务器未正确启动
- python - 如何在 GitBash 中将 Python 2 代码转换为 Python 3 代码?
- angular - 错误:使用离子路由时无法读取未定义的属性“nativeElement”
- mysql - mysql 8窗口函数错误结果
- ios - 在权利中找不到 https:反应原生
- python - 当 no_query_found 时显示 SearchQuerySet 中的所有对象
- python - Scikit Learn 用于聚类混合数据(数字和分类)