leetcode -反转链表(分步讲解三指针法)

                                    题目描述:反转一个单链表

这里我们用到的方法是三指针法。

1.首先创建3个指针,分别指向头结点,头结点的前一个结点,头结点的下一个结点

 

leetcode -反转链表(分步讲解三指针法)

 

 2.转变指针的方向,即将P2指向P1这样我们就可以将左边的看作一个新的链表,头结点为1,指向NULL

leetcode -反转链表(分步讲解三指针法)

 

3.这时候我们移动P1,使P1=P2,将P1作为头结点,方便下一次的P2转向

 

leetcode -反转链表(分步讲解三指针法)

 

4.挪动P2指针,为下一次转变指针方向做准备(这里就可以看出P3的作用是使右边的链表不至于丢失,为P2提供了下一次挪动的地址)

 

leetcode -反转链表(分步讲解三指针法)

 

5.P3完成了使命,继续往前走,循环。上几步的操作

 

leetcode -反转链表(分步讲解三指针法)

 

 6.大体思路就是这样,我们要注意的是到最后走到NULL时停下来的控制。

下图是走到后面的场景,我们可以看到此时P3和P2都走到了最后,我们要做的就是让循环停在这里,所以我们的循环条件就是P2!=NULL。为什么不是P3呢,因为P3是先走到NULL值之后P2才改变了方向走到NULL的。

 

leetcode -反转链表(分步讲解三指针法)

 

7.最后因为只有P1在头结点,所以返回P1

下面是具体的代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseList(struct ListNode* head) {
  struct ListNode *pre = NULL;        //  P1指针
  struct ListNode *cur = head;        //P2指针
    while(cur)
    {
        struct ListNode *next = cur->next;  ///P3指针
        
        cur->next = pre;    //这一步很重要:反转
        pre = cur;    
        cur = next;
    }
    return pre;        //返回P1
}

 运行结果:

leetcode -反转链表(分步讲解三指针法)

leetcode -反转链表(分步讲解三指针法)