赞
踩
反转链表是一个经典的链表操作问题,通常使用迭代的方法实现。在理解和实现这种操作时,定义三个指针(`pre`、`cur`、`nxt`)的思考模型非常有助于理清逻辑。这里详细解释这种思考模型和为什么需要这些指针。
### 反转链表的思考模型
1. **初始状态**:
- **pre**:指向已反转部分的前一个节点,初始时为 `null`。
- **cur**:当前处理的节点,初始时为链表的头节点 `a`。
- **nxt**:暂存 `cur` 的下一个节点,以防丢失,初始时也为 `a`。
2. **迭代反转**:
- 逐个节点反转链表的指针指向,并更新 `pre`、`cur` 和 `nxt` 三个指针,以便继续处理链表中的下一个节点。
3. **反转过程**:
- 先保存当前节点 `cur` 的下一个节点 `nxt`。
- 将当前节点 `cur` 的 `next` 指针指向前一个节点 `pre`,实现反转。
- 移动 `pre` 和 `cur` 到下一个节点位置,以继续下一次迭代。
### 详细步骤解释
1. **初始化指针**:
- `pre` 为 `null`,因为反转后链表的第一个节点将指向 `null`。
- `cur` 为 `a`,表示从链表头开始处理。
- `nxt` 也为 `a`,用来暂存当前节点 `cur` 的下一个节点。
2. **迭代反转**:
- 使用 `while` 循环遍历链表,直到 `cur` 为 `null`。
- 在每次迭代中:
- `nxt = cur.next`:保存当前节点的下一个节点,以防丢失。
- `cur.next = pre`:反转当前节点的指针,使其指向前一个节点。
- `pre = cur`:将 `pre` 移动到当前节点。
- `cur = nxt`:将 `cur` 移动到下一个节点。
3. **返回新的头节点**:
- 迭代结束后,`cur` 为 `null`,而 `pre` 指向反转后的链表的头节点,返回 `pre` 即可。
### 为什么需要三个指针
- **pre**:用于记录反转后链表的前一个节点,初始为 `null`。
- **cur**:用于遍历链表,指向当前处理的节点。
- **nxt**:用于暂存当前节点的下一个节点,避免在反转过程中丢失对链表剩余部分的引用。
### 代码示例
```java
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
public class ReverseList {
// 反转以 a 为头结点的链表
public ListNode reverse(ListNode a) {
ListNode pre = null;
ListNode cur = a;
ListNode nxt = a;
while (cur != null) {
nxt = cur.next; // 保存当前节点的下一个节点
cur.next = pre; // 反转当前节点的指针
pre = cur; // pre 移动到当前节点
cur = nxt; // cur 移动到下一个节点
}
// 返回反转后的头结点
return pre;
}
public static void main(String[] args) {
ReverseList rl = new ReverseList();
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
head.next.next.next = new ListNode(4);
head.next.next.next.next = new ListNode(5);
ListNode result = rl.reverse(head);
// 输出反转后的链表
while (result != null) {
System.out.print(result.val + " ");
result = result.next;
}
}
}
```
### 总结
反转链表使用 `pre`、`cur` 和 `nxt` 三个指针的思考模型本质上是将链表节点的指针方向逐个反转,并通过三个指针的移动来维护对链表的完整访问。这个模型简洁高效,可以帮助我们清晰地理解和实现链表反转操作。
// 返回反转后的头结点
return pre;
}
public static void main(String[] args) {
ReverseList rl = new ReverseList();
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
head.next.next.next = new ListNode(4);
head.next.next.next.next = new ListNode(5);
ListNode result = rl.reverse(head);
// 输出反转后的链表
while (result != null) {
System.out.print(result.val + " ");
result = result.next;
}
}
}
总结
反转链表使用 pre、cur 和 nxt 三个指针的思考模型本质上是将链表节点的指针方向逐个反转,并通过三个指针的移动来维护对链表的完整访问。这个模型简洁高效,可以帮助我们清晰地理解和实现链表反转操作。
完整性问题
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。