指针交接瞬间

一句话 a->next = b->next 只是"复制指针"(让 a->next 指向 b->next 指向的同一个节点);“插入"是两步的组合:先让新节点接住后面的链,再让前面的节点改指新节点。两步之间,两个指针会短暂指向同一个节点——这就是交接瞬间。

head->next = dummy->next 的意思是:把 dummy->next 的值(一个地址)赋给 head->next。

  • 右边是"源”,左边是"目标"。
  • 执行完这一行,head->next 和 dummy->next 指向同一个节点。
  • 单看这一行,它只是复制指针,不是插入。

假设当前状态:

1
2
dummy → 2 → 1 → null
head → 3 → 4 → null

第 1 步 head->next = dummy->next(先接住后面的链):

1
2
dummy → 2 → 1 → null
head → 3 → 2 → 1 → null     ← 交接瞬间:head 和 dummy 同时指着 2

第 2 步 dummy->next = head(前面的节点改指新节点):

1
dummy → 3 → 2 → 1 → null     ← 插入完成

交接瞬间 第 1 步执行后的一瞬间,两个指针指向同一个节点,这是刻意的——新节点先"抓住"后面的链,前面的节点才敢"松手"。不是 bug。

如果先做 prev->next = newNode,再做 newNode->next = prev->next:

1
2
3
prev->next 已经变成 newNode
再执行 newNode->next = prev->next 就是 newNode->next = newNode
→ 自己指向自己,成环

所以顺序固定:先接后面,再改前面。

1
2
newNode->next = prev->next;   // ① 新节点接住后面的链
prev->next = newNode;         // ② 前面的节点改指新节点
1
2
3
4
ListNode* next = head->next;   // 先保存下一个,防止断链
head->next = dummy->next;      // 接住已反转部分的头
dummy->next = head;            // 改指新节点
head = next;
1
2
3
4
5
ListNode* a = prev->next;
ListNode* b = a->next;
a->next = b->next;    // a 先接住 rest
b->next = a;          // b 指回 a
prev->next = b;       // 前面的链接上 b

改指针之前,先保证后面的链不会丢:

  • 要读的旧指针,先存下来(next = cur->next);
  • 新节点要接的链,先接上(head->next = dummy->next)。
  • 单行赋值 = 复制指针(两个指针指向同一个节点)。
  • 两步组合 = 插入(先接住,再松手)。
  • 口诀:先接后面,再改前面;改指针前,先防断链。
  • 能说出 head->next = dummy->next 执行后,哪两个指针指向同一个节点
  • 能把"标准插入两步"默写出来
  • 能解释为什么顺序不能反(会成环)
  • 能指出反转头插法和 swapTwo 里的"先接后面,再改前面"
  • 能说出一条总规则:改指针前先防断链

相关内容