Golang 指针反向链表混淆



我是 Golang 的新手,对指针在这里的工作方式有点困惑,我以反向链表问题为例。

func reverseList(head *ListNode) *ListNode {
var prev *ListNode = nil
for {
if head == nil {
break
}
temp := head
head = head.Next
temp.Next = prev
prev = temp
}
return prev
}

在这种情况下,temphead指向相同的内存位置。但是如果我把行放在head = head.Next前面temp.Next = prevhead.Next将指向 nil。

当我们说temp.Next = prev时引擎盖下发生了什么.我们是说temp所指的结构现在发生了变化,因此,如果我把这条线放在head = head.Next上面,那么head现在也指向这个改变的结构?

我想为了改变head.Next的实际值,我们将不得不取消引用它?

我有点困惑为什么这不起作用

func reverseList(head *ListNode) *ListNode {
var prev *ListNode = nil
for {
if head == nil {
break
}
temp := head   
temp.Next = prev
prev = temp
head = head.Next <--- CHANGED ORDERING HERE
}
return prev
}

它不起作用,因为您在第一次迭代时使head无效。以下是流程:

temp := head   
// Since temp is a pointer, any modifications made to it will also
// impact head. So when you set temp.Next here, you're also setting
// head.Next. Since prev is always nil on the first iteration, you've
// set head.Next = nil.
temp.Next = prev
prev = temp
// This will set head to nil, always.
head = head.Next

在正确的版本中,在对head = head.Next进行任何写入之前更新它意味着您已经移动到下一个元素,因此可以安全地覆盖该值。

实际上,第二个版本所做的是剪掉列表中除第一个元素之外的所有元素。如果您在调用此函数之前没有引用第二个元素,那么它们现在处于不确定状态,并且会被垃圾收集。

基于注释的更新:
当您执行类似temp := head的操作时,您会说"创建一个名为temp的指针并将其指向head指向的相同内容"。如果您随后修改temp指向的内容(例如,执行temp.Next = prev),则在读取head指向的数据时,您还将看到更改,因为它仍然指向同一位置。

当你做head = head.Next时,你说的是"更新head指向head.Next指向的任何位置"。这会更新head自身,而不是它指向的数据,因此您不会看到与temp相关的任何更改。

以下是了解有关指针的更多信息的好资源:https://dave.cheney.net/2017/04/26/understand-go-pointers-in-less-than-800-words-or-your-money-back

相关内容

  • 没有找到相关文章

最新更新