单向链表原地反转需用prev、cur、next三指针,先暂存cur->next再改指向,循环结束prev为新头;须判空链表和单节点,while条件用cur避免空指针解引用;递归法简洁但栈溢出风险高,返回值才是新头不可误用原head。

用 next 指针原地翻转,别新建节点
单向链表反转本质是把每个节点的 next 指向“调个头”,从指向后一个变成指向前一个。最常见错误是边遍历边改 next 却丢了后续节点——比如写成 cur->next = prev; cur = cur->next;,这时 cur 已经变成 prev,链表断了。
正确做法是提前存好下一个节点:
- 用三个指针:
prev(已反转部分头)、cur(当前处理节点)、next(暂存cur->next) - 每轮先
next = cur->next,再cur->next = prev,最后prev = cur; cur = next; - 循环结束时
prev就是新头节点
nullptr 判空和边界情况必须检查
空链表(head == nullptr)和单节点链表(head->next == nullptr)都应直接返回 head。漏掉这些,代码在面试或单元测试里一跑就崩。
典型错误现象:Segmentation fault (core dumped),尤其在 while 循环条件里只写 cur != nullptr 却没保证 cur 非空就访问 cur->next。
立即学习“C++免费学习笔记(深入)”;
- 入口第一行加
if (!head) return head; - while 条件用
cur而非cur->next,避免解引用空指针 - 反转后记得把原头节点的
next设为nullptr(虽然循环中已自然完成,但显式写更稳)
递归写法简洁但栈空间有风险
递归版本代码短:找到尾节点返回它作为新头,回溯时改当前节点的 next->next 和 next。但它隐式用了 O(n) 栈深度。
实际工程中,链表稍长(比如上万节点)就可能栈溢出;面试时若不说明限制,容易被追问“如果链表超长怎么办”。
- 递归终止条件必须是
head == nullptr || head->next == nullptr - 关键两步:先
newHead = reverseList(head->next),再head->next->next = head; head->next = nullptr; - 别忘了最后返回
newHead,不是head
反转后原 head 不再是头,别误用
这是最容易被忽略的语义陷阱。反转完成后,原来的 head 节点变成了尾节点,它的 next 是 nullptr。如果后续代码还拿 head 当头去遍历或释放,会只处理一个节点甚至崩溃。
- 函数返回值才是新链表头,必须用返回值继续操作
- 调试时可用
printf或日志打一下新头节点的值,确认是否真翻过来了 - 若需保持接口不变(比如函数 void 类型),得传入二级指针或引用参数来更新头指针
链表反转看着简单,真正写对要同时盯住指针指向、内存访问顺序、边界判空三件事。少一个,运行时就给你颜色看。










