C++单链表交换指定值节点与头节点(仅改指针)异常排查
单链表节点交换错误修复方案
核心错误原因
- 指针修改逻辑完全错误:
原代码中head = cur; head->next = cur->next;等价于把cur的next赋值给自己,属于无效操作;后续将原头节点的next改回原后继的操作也是冗余操作,完全没有把原头节点挂到目标节点前驱prev的后面,也没有把原头节点之后到目标节点之前的链表段挂到新头节点后面,导致中间节点全部丢失,最终只能遍历到新头节点及其后续节点。 - 未输出值不存在的提示:判断值不在链表中的分支里,漏写了
cout,导致提示语不会打印。 - 遍历无意义全量执行:查找目标节点的两次遍历都没有设置break,会遍历完整个链表,存在性能浪费,且如果有重复值会匹配最后一个出现的值,不符合常规查找逻辑。
修正后代码
void IntSLList::swap_nodes(int val) { if (head == 0) { cout << "\nThe linked list is empty.\n"; return; } // 查找是否存在目标值,找到即终止 bool isExist = false; for (IntSLLNode *tmp = head; tmp != 0; tmp = tmp->next) { if (tmp->info == val) { isExist = true; break; } } if (!isExist) { cout << "\nThe entered value is not in the linked list.\n"; return; } // 无需交换的场景直接返回 if ((head == tail) || (head->info == val)) { cout << "\nThe linked list will be printed exactly the same\n"; return; } // 查找目标节点及其前驱节点,找到即终止 IntSLLNode *prev = NULL, *cur = NULL; for (IntSLLNode *tmp = head; tmp->next != 0; tmp = tmp->next) { if (tmp->next->info == val) { prev = tmp; cur = tmp->next; break; } } // 保存关键节点指针 IntSLLNode *old_head = head; IntSLLNode *cur_next = cur->next; IntSLLNode *old_head_next = old_head->next; // 调整指针完成交换 prev->next = old_head; old_head->next = cur_next; cur->next = old_head_next; head = cur; // 如果目标节点是原尾节点,更新尾指针 if (cur_next == NULL) { tail = old_head; } }
逻辑说明
以示例0(原头节点) -> 1 -> 2 -> 3(目标节点) ->4 ->5为例,交换步骤如下:
- 保存目标节点后继
cur_next=4、原头节点后继old_head_next=1 - 目标节点前驱2的next指向原头节点0
- 原头节点0的next指向原目标节点后继4
- 目标节点3的next指向原头节点后继1
- 更新链表头为目标节点3
最终得到的链表为3->1->2->0->4->5,符合预期要求。
内容的提问来源于stack exchange,提问作者tuana
相关产品推荐
相关产品推荐

