单链表反转的核心是原地修改next指针方向,关键在于不丢节点、不错指针、不越界;需用三指针迭代(prev/curr/next)或递归(信任子问题+回溯接链),并严格处理空链表、单节点、双节点三类边界。

单链表反转的核心是原地修改每个节点的 next 指针方向,不新建节点、不借助额外容器。关键不在“怎么写”,而在“怎么不丢节点、不错指针、不越界”。下面从实操角度讲清三个核心环节。
迭代法:三指针配合,边走边翻
这是最常用、空间复杂度 O(1) 的做法。本质是用 prev、curr、next 三个变量控制翻转节奏:
- prev 始终指向已反转部分的头节点(初始为 null)
- curr 指向当前待处理节点(初始为 head)
-
next 是临时变量,每次循环开头就保存
curr.next,防止链表断裂
每轮操作顺序固定:先存 next → 再改 curr.next → 然后 prev 和 curr 同步前移。循环结束时 curr 为 null,prev 就是新头节点。
递归法:信任子问题,回溯时接链
递归不是“从头翻”,而是“先让尾巴翻好,再把当前节点挂到尾巴后面”。它依赖两个关键动作:
- 递归终止条件必须覆盖空链表(
head == null)和单节点(head.next == null),直接返回 head - 回溯时执行两步:
head.next.next = head(把子链表尾连回来),head.next = null(断开原连接,避免成环)
注意:递归深度等于链表长度,极端情况下可能栈溢出;但逻辑更贴近“反转”的数学定义——结构对称性重建。
边界条件不能靠猜,得写死这三类
几乎所有翻车都发生在边界上。必须显式处理以下三种输入:
-
空链表(
head == null)→ 直接返回 null,不进循环也不递归 -
单节点链表(
head != null && head.next == null)→ 迭代中循环不执行,递归中直接返回,结果仍是原节点 -
双节点链表(如 1→2→null)→ 是检验指针移动是否正确的最小有效案例,手动走一遍能暴露
prev或next使用错误
测试时别只用 1→2→3→4→5,一定要加这三组用例,否则上线后遇到空列表或用户只传一个节点,程序就崩。
常见错误点与避坑提示
写对不难,写稳才见功底。高频出错位置集中在:
- 没保存
curr.next就改curr.next = prev→ 下一节点丢失,链表截断 - 返回了
curr而不是prev→ 实际返回的是 null,结果为空 - 递归中漏写
head.next = null→ 最后形成环:5→4→3→2→1→5 - 判断边界用
head.next == null却没先判head == null→ 空指针异常
只要把指针保存、方向修改、边界拦截这三件事拆开验证,反转链表就是个确定性过程,不玄学也不靠运气。











