Golang指针与反转链表困惑:代码行顺序影响的原理问询
搞懂Go指针在反转链表中的工作机制
嘿,作为Go新手,纠结指针在反转链表里的逻辑太正常了!咱们一步步拆解,你就能明白为什么调换那两行代码的顺序会出问题。
首先先明确ListNode的结构(你代码里没写,但默认是这样的):
type ListNode struct { Val int Next *ListNode }
先看原代码的正确逻辑
原代码的步骤是先移动head,再修改当前节点的指向,咱们用链表1->2->3->nil来走一遍:
- 初始化
prev = nil,head指向节点1。 - 进入循环:
temp := head:此时temp和head都是指向节点1的内存地址(相当于给同一个节点贴了两个标签)。head = head.Next:把head这个标签移到节点2(这一步很关键!我们先把后续节点的引用保存下来,避免后续修改影响它)。temp.Next = prev:修改节点1的Next字段,让它指向prev(也就是nil),现在节点1变成1->nil。prev = temp:把prev标签移到节点1,此时prev是反转后链表的临时头。
- 下一轮循环处理节点2,重复上述步骤,最后得到反转后的链表
3->2->1->nil。
为什么调换顺序会出错?
如果把temp.Next = prev放在head = head.Next之前,咱们还是用同一个例子走一遍:
- 初始化
prev = nil,head指向节点1。 - 进入循环:
temp := head:temp和head都指向节点1。temp.Next = prev:直接修改节点1的Next字段为nil(因为temp是指向节点1的指针,修改temp.Next就是修改节点1本身的属性)。head = head.Next:这时候head.Next已经被改成nil了,所以head直接变成nil,循环直接break。
- 最后返回
prev = 1,得到的链表只有1->nil,后续的节点2、3完全没处理到!
核心本质:指针指向的是共享对象
在Go里,指针变量(比如temp、head)就像指向内存地址的标签,多个指针可以指向同一个对象。当你通过指针修改对象的字段(比如temp.Next),本质是修改那个内存地址里的实际数据,所有指向该对象的指针都会看到这个变化。
原代码的顺序之所以正确,是因为先把head这个标签移到下一个节点,再修改原来节点的Next,这样就不会切断head到后续节点的链路;而调换顺序后,修改当前节点的Next会直接把head的后续链路打断,导致循环提前结束。
内容的提问来源于stack exchange,提问作者Somnium
相关产品推荐
相关产品推荐

