链表反转难哭新手?用“手拉手掉头”法,3个指针搞定,笑到会写!
你有没有过这种崩溃:对着链表反转代码看半天,指针绕来绕去,越看越像“打结的耳机线”?其实链表反转没那么玄乎,核心就是“让每个节点掉个头拉手”,像小朋友排队转身一样简单!今天用“幼儿园排队”的段子给你讲透Java实现,3个指针+5步操作,看完就能写代码,再也不用被指针绕晕~
先懂链表:像小朋友手拉手排队,断一个就“队伍散架”
要反转链表,得先搞懂链表的“脾气”:它不像数组那样有固定位置,而是靠“指针”(每个节点里的`next`)手拉手连起来的,就像幼儿园小朋友排队,每个人只知道“拉着前面人的衣服”,一旦有人松手,后面的队伍就跟丢了。
举个例子:链表`1→2→3→4→null`,就像小朋友排队“1拉2,2拉3,3拉4,4后面没人”。反转的目标就是让队伍变成`4→3→2→1→null`,相当于让每个小朋友转身,改成“4拉3,3拉2,2拉1,1后面没人”——关键是转身时不能让队伍散架,得提前记住下一个要拉的人!
核心思路:3个指针当“指挥员”,防止队伍散架
反转链表的秘诀,就是用3个指针当“指挥员”,分别盯着“当前要转身的小朋友”“已经转好身的前一个小朋友”“还没转身的后一个小朋友”。这3个指针在Java里通常叫:
- `prev`:前一个节点(已经转好身,站在当前节点左边);
- `curr`:当前节点(正要转身的小朋友);
- `nextTemp`:后一个节点(还没转身,提前记住,防止转身时跟丢)。
就像排队转身时,你(`curr`)要先记住右边的小明(`nextTemp`),再转身拉左边的小红(`prev`),最后让小红(`prev`)和你(`curr`)都往右边挪一步,重复这个动作,直到所有人都转完身。
Java实现5步走:幼儿园排队 analogy 全还原
用“1→2→3→4→null”反转成“4→3→2→1→null”为例,每一步都对应排队转身的场景,代码一看就懂:
1. 初始化指针:给指挥员“分配任务”
第一步先给3个指针“定岗”:
- `prev` 初始为`null`:刚开始没有小朋友转身,“已经转好身的队伍”是空的;
- `curr` 初始为链表头节点(1):从第一个小朋友开始转身;
- `nextTemp` 暂时不用管,后面每次转身前再赋值。
Java代码:
// 定义链表节点
class ListNode {
int val;
ListNode next;
ListNode(int val) { this.val = val; }
}
public class ReverseList {
public ListNode reverseList(ListNode head) {
ListNode prev = null; // 前一个节点(初始空)
ListNode curr = head; // 当前节点(从第一个开始)
ListNode nextTemp = null; // 后一个节点(临时保存)
// 后面步骤写这里...
}
}2. 遍历链表:逐个小朋友转身(循环开始)
只要还有没转身的小朋友(`curr != null`),就一直重复转身操作。就像排队时,从第一个小朋友开始,直到最后一个都转完身。
循环条件:
while (curr != null) { // 还有小朋友没转身,继续
// 转身操作写这里...
}3. 保存后一个节点:记住“下一个要拉的人”
转身前,必须先记住右边的小朋友(`nextTemp = curr.next`),不然转身时一松手,后面的队伍就丢了!比如当前是1(`curr=1`),要先记住2(`nextTemp=2`),再转身拉`prev`(null)。
代码:
nextTemp = curr.next; // 保存后一个节点(防止跟丢)4. 反转指针:小朋友转身,拉前一个人的手
这是最关键的一步!让当前小朋友(`curr`)松开右手,转身拉左边`prev`的手(`curr.next = prev`)。比如1(`curr=1`)原来拉2,现在转身拉`prev`(null),变成“1→null”。
代码:
curr.next = prev; // 当前节点转身,指向前面的节点5. 移动指针:指挥员“向右挪一步”
转身完成后,让`prev`和`curr`都往右边挪一步,准备下一个小朋友转身:
- `prev` 挪到`curr`(现在`prev`变成1,代表“已经转好身的队伍是1→null”);
- `curr` 挪到之前保存的`nextTemp`(现在`curr`变成2,下一个要转身的是2)。
代码:
prev = curr; // 前一个节点右移
curr = nextTemp; // 当前节点右移,准备下一次转身循环结束:新头节点诞生
当`curr`变成`null`(最后一个小朋友4也转完身了),`prev`就指向最后一个节点4,这时候4就是新的头节点,整个链表已经反转成“4→3→2→1→null”。最后返回`prev`就行!
完整代码:
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
ListNode nextTemp = null;
while (curr != null) {
nextTemp = curr.next; // 1. 记住后一个
curr.next = prev; // 2. 转身拉手
prev = curr; // 3. 前一个右移
curr = nextTemp; // 4. 当前右移
}
return prev; // 最后prev就是新头节点
}避坑提醒:这2个坑能让链表“打结”,新手必踩!
1. **忘记保存`nextTemp`,直接反转指针**:就像小朋友转身时没记住下一个是谁,转身完发现后面的队伍不见了,链表直接断裂成两段。比如`curr=1`时,没存`nextTemp=2`,直接`curr.next=prev`,之后再也找不到2、3、4了,链表变成“1→null”,后面的节点全丢了!
2. **循环结束后返回`curr`而不是`prev`**:最后`curr`是`null`,返回`null`相当于告诉调用者“反转后的链表是空的”,纯属白忙活。记住:转完身的队伍头是`prev`,不是`curr`!就像排队转身完,新的队伍带头人是最后一个转身的4(`prev=4`),而`curr`已经走到队伍外面(`null`)了。
互动时间:来测测你的“链表反转实战力”!
1. 用今天的代码反转链表`1→2→3`,循环执行几次后结束?(提示:每个节点转一次,3个节点执行3次循环)
2. 要是链表只有一个节点(`1→null`),反转后会变成啥?(提示:`curr`一开始是1,循环一次后`curr=null`,返回`prev=1`,还是1→null)
3. 你第一次写链表反转时,踩过“指针绕晕”的坑吗?比如把`curr.next`赋值错,导致链表打结?评论区说说你的“翻车经历”!
评论区交出你的答案,前3名答对的送“Java链表操作手册”(含反转、环检测、中间节点查找的通俗讲解+代码模板)!关注我,下期揭秘“链表反转的递归写法”——用“一句话搞定反转”,帅到飞起~
相关文章
- Spring Boot中对接Twilio以实现发送验证码和验证短信码
- Spring Boot 3.5:这次更新让你连配置都不用写了,惊不惊喜?
- Spring Boot+Pinot实战:毫秒级实时竞价系统构建
- SpringBoot敏感配置项加密与解密实战
- SpringBoot 注解最全详解,建议收藏!
- Spring Boot 常用注解大全:从入门到进阶
- SpringBoot启动之谜:@SpringBootApplication如何让配置化繁为简
- Springboot集成Kafka原理_spring集成kafka的原理
- Spring Boot中@Data注解的深度解析与实战应用
- 大佬用1000字就把SpringBoot的配置文件讲的明明白白!
