链表逆置(三指针法)(c语言)

1.这种是我学习了一些其它三指针法链表逆置方法后,结合本人的强迫症最后得到的优美且健全的实现方案。循环条件是p3不为空,也就是最后一次进入循环条件时候p3的指向是原链表最后一个元素,完成最后一次循环后p2在原链表的末尾位置,也就是新链表的表头位置。所以,在改变p2指向后,返回的头指针是p2而不是p1。

//分两段逻辑处理节点:第1到n-1个节点,第n个节点
ListNode* reverse(ListNode* head) {
    if(head==NULL) return NULL;
    ListNode *p1 = NULL, *p2 = head, *p3=p2->next;
    while (p3) {//处理第1到n-1个节点
        p2->next = p1;  //p2的指向反转
        p1 = p2;        //p1后移
        p2 = p3;        //p2后移,
        p3=p2->next;    //p3后移,
    }//此时p2在最原链表最末端的节点位置,此时p2指向最后的NULL

    p2->next=p1;//反转p2指向
    return p2;
}

2.这是标准写法(我将变量名换成了我自己容易理解的p1\p2\p3),省去了对空链表的单独逻辑判断,但是声明p3的时候没有初始化以及p3后移的顺序在反转指针前面,让我感觉到“不美”,这种方法我大概率今天记了明天就忘了,所以我还是更加中意自己的第一种写法。还有区别是这个方法是利用p2不为NULL进入循环条件,故最后一次进入循环的时候p2指向的是原链表的最后一个节点,当执行完最后一次循环的时候,p1会后移到原链表的最后一个节点,所以最后链表反转后链头在p1上。

ListNode* reverse_standard(ListNode* head) {
    ListNode *p1 = NULL, *p2 = head, *p3;
    while (p2) {
        p3 = p2->next;  // 保存下一个节点
        p2->next = p1;  // 反转指针
        p1 = p2;        // p1前移
        p2 = p3;        // p2前移
    }
    return p1;
}

但是这种标准写法的好处在于保证了指针操作的“先保存、再操作、后移动”,所以自己应该要逐步适应这种规则。

3.还有一种写法

//分两段逻辑处理节点:第1到n-1个节点,第n个节点
ListNode* reverse(ListNode* head) {
    if(head==NULL) return NULL;
    ListNode *p1 = NULL, *p2 = head, *p3=p2->next;
    while (p2) {
        p2->next = p1;  //p2的指向反转
        p1 = p2;        //p1后移
        p2 = p3;        //p2后移,
        if(p2!=NULL) p3=p2->next;    //p3后移,
    }
  
    return p1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值