【问题标题】:Golang Pointer Reverse Linked List ConfusionGolang 指针反向链表混淆
【发布时间】:2018-10-07 17:20:51
【问题描述】:

我是 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 指向同一个内存位置。但是如果我将temp.Next = prev 放在head = head.Next 之前,head.Next 将指向零。

当我们说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
}

【问题讨论】:

  • 与 C 不同,Go 自动取消引用指向结构的指针。如果p 是指针如果p 是结构变量,则您可以使用p.Next 访问结构成员。
  • 我不知道是这样的,直到现在我才真正质疑过更改结构字段!

标签: pointers go linked-list


【解决方案1】:

它不起作用,因为您在第一次迭代时使 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 意味着您已经移至下一个元素,因此覆盖该值是安全的。

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

基于 cmets 的更新:
当您执行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

【讨论】:

  • 当我设置head = head.Next 它也应该设置temp 等于head.Next 对吧?但是为什么之后我设置temp.prev = prev就不再影响head了呢?
  • 是因为head = head.Next 将它分配给另一个指针而不是改变它吗?那么headtemp 不再相关?
  • 我添加了一些关于指针如何工作的细节,如果这有帮助,请告诉我。但是对于第二条评论,是的,设置head = head.Next 会使head 指向与temp 不同的数据,所以现在修改两者是独立的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-05
  • 2013-07-07
  • 1970-01-01
  • 1970-01-01
  • 2016-06-28
相关资源
最近更新 更多