链表 | 指针法解决链表反转问题

链表反转问题描述

反转一个单链表,示例如下:

输入: 1 -> 2 -> 3 -> 4 -> 5

输出: 5 -> 4 -> 3 -> 2 -> 1

链表的特性

- 链表是只允许顺序访问的线性顺序结构, 这里强调这个, 因为后续在链表断开的时候, 需要用到temp变量存储断开的后续链表就是这个原因.

- 链表之间通过指针相连, 指针访问, 每个节点仅有一个指针

- 链表的尾节点也有指针, 指向null, 这是我们做题遍历循环终止的一个重要条件.

解题思路

这题目有多种解题思路, 本篇着重使用迭代法完成链表的反转.

当使用迭代法反转链表时,我们使用两个指针:prevcurrent,以及一个额外的指针next来帮助反转过程。

prev指向给定链表头节点的前一个位置,  初始化设置成null, 可以理解成一个新的链表, 最终的目的也是需要将prev变成反转后的链表.

current一开始指向给定链表的头节点, 然后挨个往后顺序移动, 直到current节点为空.

next用来表示current之后的链表.  我们现在来看一下逐步循换一步一步往prev头节点插入值和指向的方式变成一个反转后的链表.

完成反转的思想是在current当前节点,先存储current.next的链表为temp临时变量, 然后切断current与current.next的指向,将current.next的指向转变成指向prev(指针转换方向), 再把current赋值给prev(赋值的目的就是让prev成为反转后的链表), 最后更新current的值为temp, 继续下一次同样的操作, 直到current为null, 循环终止.

这样理解起来有点困难, 看一下反转在每一个循环步骤里的数据变化, 就可以明白了.

原始链表:  1 -> 2 -> 3 -> 4 -> 5

每一次循环的判断条件: current节点不能为空, 为空说明已经遍历到了链表的最后位置

每一次循环必做的事情: temp存储current.next, 切掉current与current.next的指向, 指向prev,再将current赋值给prev, 最后更新current的值更新成temp.

初始化:

prev: null

current的值是1, current表示的链表是1 -> 2 -> 3 -> 4 -> 5

current.next的值是2, temp表示的链表是 2 -> 3 -> 4 -> 5


第一次循环过程:
- temp存储current.next, 因此temp的值是2 -> 3 -> 4 -> 5

- 切掉current与current.next的指向, 指向prev, 因此current的值是 1 , 对应的链表 1-> null

- 再将current赋值给prev, 因此 prev的值是1, 对应的链表 1 -> null

- 更新current的值为temp, current对应的值是2, 对应的链表  2 -> 3 -> 4 -> 5


第二次循环过程:

- temp存储current.next, 因此temp的值是 3 -> 4 -> 5

- 切掉current与current.next的指向, 指向prev, 因此current的值是 2 , 对应的链表

   2 -> 1-> null

- 再将current赋值给prev, 因此 prev的值是2, 对应的链表 2 -> 1-> null

- 更新current的值为temp, current对应的值是3, 对应的链表 3 -> 4 -> 5


第三次循环过程:

- temp存储current.next, 因此temp的值是 4 -> 5

- 切掉current与current.next的指向, 指向prev, 因此current的值是 3 , current对应的链表

   3 -> 2 -> 1-> null

- 再将current赋值给prev, 因此 prev的值是3, prev对应的链表 3 -> 2 -> 1-> null

- 更新current的值为temp, current对应的值是4, current对应的链表 4 -> 5


第四次循环过程:

- temp存储current.next, 因此temp的值是 5

- 切掉current与current.next的指向, 指向prev, 因此current的值是 4, current对应的链表

  4 ->-> 2 -> 1-> null

- 再将current赋值给prev, 因此 prev的值是4, prev对应的链表 4-> 3 -> 2 -> 1-> null

- 更新current的值为temp, current对应的值是5, current对应的链表  5


第五次循环过程:

- temp存储current.next, 因此temp的值是 null

- 切掉current与current.next的指向, 指向prev, 因此current的值是 5, current对应的链表

  5 -> 4 ->-> 2 ->-> nul

- 再将current赋值给prev, 因此 prev的值是4, prev对应的链表  5 ->  4 -> 3 -> 2 ->-> null

- 更新current的值为temp, current对应的值是null, 循环结束

java代码示例

public class ReverseLinkedListPointer {
    /**
     * 反转链表
     *
     * @param head 头节点
     * @return 反转后的头节点
     */
    public ListNode reverse(ListNode head) {
        // 初始化前一个节点为null,因为反转后的最后一个节点指向null
        ListNode prev = null;
        // 初始化当前节点为头节点
        ListNode current = head;

        // 遍历链表
        while (current != null) {
            // 暂存当前节点的下一个节点,防止丢失链表信息
            ListNode next = current.next;
            // 将当前节点的next指向前一个节点,实现反转
            current.next = prev;
            // 赋值给prev, 更新新链表
            prev = current;
           //current指针到下一位置
            current = next;
        }

        // 返回反转后的头节点
        return prev;
    }
}

你可能感兴趣的:(算法,链表,数据结构,算法)