单链表节点交换异常求助:交换首节点与第三节点时出错
问题原因分析
首先咱们先还原一下你的链表初始状态:你有5个节点,调用interchange(list, list->pNext->pNext)时,p是头节点(记为节点1),q是第三个节点(记为节点3),初始链表结构是:
1 → 2 → 3 → 4 → 5 → NULL
你出问题的语句p->pNext->pNext = q->pNext->pNext;,拆解一下:
p->pNext是节点2,q->pNext->pNext是节点5(因为q->pNext是节点4)- 这行代码直接把节点2的next指针指向了节点5,相当于把节点3、4从链表中直接切断了,它们变成了无人引用的野节点,同时链表结构变成了
1→2→5→NULL,后续任何对原节点3、4的访问都会触发内存异常,这就是问题的核心。
而且更关键的是,你这行代码的逻辑完全不符合「交换两个节点位置」的需求——交换节点需要调整多个关联指针,而不是只改这一个。
解决办法
要正确交换头节点p(节点1)和第三个节点q(节点3),需要完整梳理所有需要调整的指针,以下是修正后的完整函数:
void interchange(SList*& p, SList*& q) { // 1. 保存关键指针,避免被覆盖后丢失 SList* prev_q = p->pNext; // q的前驱节点(节点2) SList* q_next = q->pNext; // q的后继节点(节点4) // 2. 调整q前驱的指向:让节点2现在指向原来的头节点p prev_q->pNext = p; // 3. 调整原头节点p的指向:让节点1指向q原来的后继节点4 p->pNext = q_next; // 4. 调整q的指向:让节点3指向原来的节点2 q->pNext = prev_q; // 5. 更新头指针:因为现在q变成了新的头节点,要通过引用同步到外部 p = q; }
执行完这个函数后,链表结构会变成预期的交换状态:
3 → 2 → 1 → 4 → 5 → NULL
另外补充几个注意点:
- 如果你交换的节点不是头节点和中间节点(比如两个都是中间节点),还需要先找到
p的前驱节点,但你的场景里p是头节点,所以不需要额外处理它的前驱。 - 一定要先保存所有需要复用的指针,否则在修改指针的过程中,原来的指针会被覆盖,导致无法找到对应的节点。
内容的提问来源于stack exchange,提问作者David Zaberca
相关产品推荐
相关产品推荐

