合并有序链表(学习如何移动链表 p2 = p2.next;

  1. p2 = p2.next;:

    • 这一行代码的作用是将 p2 向前移动到它的下一个节点。
    • 原本 p2 指向的是某个节点,这一行执行后,p2 指针将指向它的下一个节点,准备进行下一次比较和可能的连接。
    • 这一步是为了在下一次循环时 p2 能够指向它的下一个节点,使得 p2 和 p1 继续比较和合并操作。

ListNode mergeTwoLists(ListNode l1, ListNode l2) { // 虚拟头结点 ListNode dummy = new ListNode(-1), p = dummy; ListNode p1 = l1, p2 = l2; while (p1 != null && p2 != null) { // 比较 p1 和 p2 两个指针 // 将值较小的的节点接到 p 指针 if (p1.val > p2.val) { p.next = p2; p2 = p2.next; } else { p.next = p1; p1 = p1.next; } // p 指针不断前进 p = p.next; } if (p1 != null) { p.next = p1; } if (p2 != null) { p.next = p2; } return dummy.next; } 解释 p.next = p2; p2 = p2.next;

在这段代码中,关键部分是以下两行:

```java
p.next = p2;
p2 = p2.next;
```

### 解释

1. **`p.next = p2;`**:
   - 这一行代码的作用是将指针 `p` 的 `next` 域指向 `p2` 当前所指向的节点。
   - `p` 是当前合并链表的尾节点,通过 `p.next = p2`,将 `p2` 当前的节点接到合并链表的末尾。
   - 换句话说,这一行代码将 `p2` 当前节点连接到新链表中。

2. **`p2 = p2.next;`**:
   - 这一行代码的作用是将 `p2` 向前移动到它的下一个节点。
   - 原本 `p2` 指向的是某个节点,这一行执行后,`p2` 指针将指向它的下一个节点,准备进行下一次比较和可能的连接。
   - 这一步是为了在下一次循环时 `p2` 能够指向它的下一个节点,使得 `p2` 和 `p1` 继续比较和合并操作。

### 图示说明

假设当前链表的结构如下:

- `p1` 指向的链表: 1 -> 4 -> 6
- `p2` 指向的链表: 2 -> 3 -> 5
- `p` 是合并链表的当前末尾节点,初始时是 `dummy` 的位置

初始情况:

```
dummy -> -1 -> null
p -> -1 -> null
p1 -> 1 -> 4 -> 6
p2 -> 2 -> 3 -> 5
```

### 执行步骤

1. **第一次比较**:
   - `p1.val (1)` 和 `p2.val (2)` 比较,`1 < 2`,所以将 `p1` 当前节点连接到 `p` 的 `next` 上,并移动 `p1`。
   
   ```java
   p.next = p1;
   p1 = p1.next;
   p = p.next;
   ```

   结果:
   ```
   dummy -> -1 -> 1 -> null
   p -> 1 -> null
   p1 -> 4 -> 6
   p2 -> 2 -> 3 -> 5
   ```

2. **第二次比较**:
   - `p1.val (4)` 和 `p2.val (2)` 比较,`4 > 2`,所以将 `p2` 当前节点连接到 `p` 的 `next` 上,并移动 `p2`。
   
   ```java
   p.next = p2;
   p2 = p2.next;
   p = p.next;
   ```

   结果:
   ```
   dummy -> -1 -> 1 -> 2 -> null
   p -> 2 -> null
   p1 -> 4 -> 6
   p2 -> 3 -> 5
   ```

3. **第三次比较**:
   - `p1.val (4)` 和 `p2.val (3)` 比较,`4 > 3`,所以将 `p2` 当前节点连接到 `p` 的 `next` 上,并移动 `p2`。
   
   ```java
   p.next = p2;
   p2 = p2.next;
   p = p.next;
   ```

   结果:
   ```
   dummy -> -1 -> 1 -> 2 -> 3 -> null
   p -> 3 -> null
   p1 -> 4 -> 6
   p2 -> 5
   ```

4. **第四次比较**:
   - `p1.val (4)` 和 `p2.val (5)` 比较,`4 < 5`,所以将 `p1` 当前节点连接到 `p` 的 `next` 上,并移动 `p1`。
   
   ```java
   p.next = p1;
   p1 = p1.next;
   p = p.next;
   ```

   结果:
   ```
   dummy -> -1 -> 1 -> 2 -> 3 -> 4 -> null
   p -> 4 -> null
   p1 -> 6
   p2 -> 5
   ```

5. **第五次比较**:
   - `p1.val (6)` 和 `p2.val (5)` 比较,`6 > 5`,所以将 `p2` 当前节点连接到 `p` 的 `next` 上,并移动 `p2`。
   
   ```java
   p.next = p2;
   p2 = p2.next;
   p = p.next;
   ```

   结果:
   ```
   dummy -> -1 -> 1 -> 2 -> 3 -> 4 -> 5 -> null
   p -> 5 -> null
   p1 -> 6
   p2 -> null
   ```

6. **剩余部分处理**:
   - `p2` 已经为 `null`,将 `p1` 剩余的部分连接到 `p` 的 `next` 上。
   
   ```java
   if (p1 != null) {
       p.next = p1;
   }
   ```

   最终结果:
   ```
   dummy -> -1 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6
   ```

   返回 `dummy.next` 即得到合并后的有序链表:
   ```
   1 -> 2 -> 3 -> 4 -> 5 -> 6
   ```

### 知识点总结

1. **链表操作**:
   - 使用指针操作进行链表节点的连接和遍历。
   - 使用 `dummy` 哨兵节点简化边界条件处理,避免处理 `null` 指针异常。

2. **条件判断和指针移动**:
   - 通过条件判断决定连接 `p1` 还是 `p2` 当前节点到新的链表。
   - 移动 `p1` 和 `p2` 指针使得它们指向下一个节点,继续比较和连接操作。

3. **合并过程**:
   - 逐步将两个有序链表合并成一个新的有序链表,保持原有链表节点的顺序。

通过上述过程,我们完成了两个有序链表的合并,保持了链表的有序性,并且每个节点都被正确地连接到新的链表中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值