
本文讲解如何仅通过调整指针(不借助额外数据结构)原地反转单链表,核心是使用三个指针(prev、curr、next)迭代翻转相邻节点间的引用关系。
在无法创建新节点、不能使用数组或栈等辅助存储的前提下,反转单链表的关键在于就地修改 next 指针的指向顺序。原始代码中试图用 first.elem = aux.elem 复制元素值,这不仅违背“仅重连指针”的约束,更无法真正改变链表结构——它只是把尾部元素值覆盖到头节点,其余节点仍保持原顺序,逻辑完全错误。
正确解法采用经典的三指针迭代法:
- prev:记录已反转部分的头节点(初始为 null);
- curr:当前待处理节点(初始为 first);
- next:暂存 curr.next,防止遍历过程中丢失后续节点。
每轮迭代中:
- 保存 curr.next 到 next;
- 将 curr.next 指向 prev(完成一次翻转);
- 将 prev 更新为 curr,curr 更新为 next,继续处理下一节点。
当 curr == null 时,prev 即为新链表的头节点,最后将其赋给 first 即可。
以下是完整、健壮的实现:
public void reverse() {
Node prev = null;
Node curr = first;
while (curr != null) {
Node next = curr.next; // 保存下一个节点
curr.next = prev; // 反转当前节点的指针
prev = curr; // 移动 prev 到当前节点
curr = next; // 移动 curr 到下一个节点
}
first = prev; // 更新头节点为原链表尾节点
} ⚠️ 注意事项:
- 时间复杂度为 O(n),空间复杂度为 O(1),完全满足“无辅助结构”要求;
- 空链表(first == null)可直接跳过循环,first = prev(即 null)仍保持正确;
- 切勿修改 elem 值——本题目标是逻辑结构反转,而非元素置换;
- 若需递归实现,虽简洁但会引入 O(n) 栈空间,不符合题目隐含的“严格原地”要求。
该方法是链表操作的基础范式,掌握其指针迁移逻辑,对理解插入、删除、检测环等其他链表算法至关重要。










