[英]Traversing a linked list with 2 pointer variables in python
假设您有一个函数将链表中节点上的每个next
值设置为它前面的val
节点的节点。 因此,如果链表是2->1->4->2
,结果链表将是2->4
因为前面的2->4
个节点是越界的。
def solve(self, node):
head = node
curr = head
while curr:
save = curr
c = 0
while c < save.val and curr:
curr = curr.next
c = c + 1
save.next = curr
return head
我有这个功能,它通过了所有的测试用例。 但是我对如何在整个函数中更新 head 值感到困惑。
Head 从函数开头的参数中复制的节点开始,然后复制到 curr 变量中。 python不是都是按值传递的吗? 为什么传入 node 的原始值不是也被返回的值?
头以复制的节点开始
这就是混淆的原因:节点没有被复制。 引用已复制。
这是示例代码中发生的情况的可视化:
它从这种情况开始:
node
↓
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ val: 2 │ │ val: 1 │ │ val: 4 │ │ val: 2 │
│ next: ───────> │ next: ───────> │ next: ───────> │ next:None │
└───────────┘ └───────────┘ └───────────┘ └───────────┘
在前两个赋值head = node
和curr = head
以及外循环( save = curr
)的第一次迭代中的赋值之后,我们有:
node
head
save
curr
↓
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ val: 2 │ │ val: 1 │ │ val: 4 │ │ val: 2 │
│ next: ───────> │ next: ───────> │ next: ───────> │ next: ───────> None
└───────────┘ └───────────┘ └───────────┘ └───────────┘
在内部循环迭代到c == 2
,我们有:
node
head
save curr
↓ ↓
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ val: 2 │ │ val: 1 │ │ val: 4 │ │ val: 2 │
│ next: ───────> │ next: ───────> │ next: ───────> │ next: ───────> None
└───────────┘ └───────────┘ └───────────┘ └───────────┘
然后执行save.next = curr
,这是列表发生变异的唯一语句:
node
head
save curr
↓ ┌────────────────┐ ↓
┌───────────┐ │ ┌───────────┐ │ ┌───────────┐ ┌───────────┐
│ val: 2 │ │ │ val: 1 │ └> │ val: 4 │ │ val: 2 │
│ next: ───────> │ next: ───────> │ next: ───────> │ next: ───────> None
└───────────┘ └───────────┘ └───────────┘ └───────────┘
在外循环的下一次迭代中,再次执行save = curr
:
node save
head curr
↓ ┌────────────────┐ ↓
┌───────────┐ │ ┌───────────┐ │ ┌───────────┐ ┌───────────┐
│ val: 2 │ │ │ val: 1 │ └> │ val: 4 │ │ val: 2 │
│ next: ──────┘ │ next: ───────> │ next: ───────> │ next: ───────> None
└───────────┘ └───────────┘ └───────────┘ └───────────┘
一旦内部循环完成, curr
将变为None
:
node
head save curr
↓ ┌────────────────┐ ↓ ↓
┌───────────┐ │ ┌───────────┐ │ ┌───────────┐ ┌───────────┐
│ val: 2 │ │ │ val: 1 │ └> │ val: 4 │ │ val: 2 │
│ next: ──────┘ │ next: ───────> │ next: ───────> │ next: ───────> None
└───────────┘ └───────────┘ └───────────┘ └───────────┘
然后再次执行save.next = curr
:
node
head save curr
↓ ┌────────────────┐ ↓ ┌────────────────┐ ↓
┌───────────┐ │ ┌───────────┐ │ ┌───────────┐ │ ┌───────────┐ │
│ val: 2 │ │ │ val: 1 │ └> │ val: 4 │ │ │ val: 2 │ └>
│ next: ──────┘ │ next: ───────> │ next: ──────┘ │ next: ───────> None
└───────────┘ └───────────┘ └───────────┘ └───────────┘
最后我们执行return head
。 这将返回与作为参数( node
)传递给函数的完全相同的引用。
注意:因为现在有两个节点无法访问,垃圾收集器可能会释放它们的内存,所以调用者最终会处于这种状态:
head
↓
┌───────────┐ ┌───────────┐
│ val: 2 │ │ val: 4 │
│ next: ────────────────────────> │ next: ────────────────────────> None
└───────────┘ └───────────┘
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.