单链表反转

写博客有一段时间了,刚开始写的时候感觉收获挺多的,每次写完感觉印象挺深刻····过了一段时间,感觉写的也都忘了个差不多了····

再接再厉吧!

链表结构体:

struct node
{
    int val;
    node* next;
    node(int val):val(val),next(NULL){};
};

单链表的反转一个比较好的思路,用三个指针(分别指向三个连续的节点)进行轮转,在循环中,每一次循环转置前两个节点的前后关系,然后将三个指针分别后移,直至循环结束。

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

                       p    q     r                            (布置好指针)

                      1<--2    3-->4-->NULL    (反转前两个节点的前后关系)

                             p    q    r                      (指针位置依次后移)

                      1<--2<--3    4-->NULL     (步骤同上)

                                    p    q     r

                      1<--2<--3<--4    NULL

                                           p    q           (r)

可以看出q==NULL是循环结束的条件,而此时r已经不能继续后移了,需要给定一个后移条件,核心语句如下:

q->next=p;
p=q;
q=r;
if(r!=NULL) r=r->next;

LeetCode中的ReverseLinkedList II,要求反转单列表中给定位置(给定初始和结束位置)的部分。思路大同小异,先循环至初始位置(需要记录下初始位置的前一个节点),再进行我们上面的反转过程,最后把反转后的部分嵌入到剩下的链表中即可。唯一需要注意的是初始位置为1的情况,这种情况下头节点是变化的。

代码如下:

class Solution {
public:
    ListNode *reverseBetween(ListNode *head, int m, int n) {
        if(head==NULL|| head->next==NULL || m==n) return head;
        m--;n--;
        ListNode* result=head;    //最终的头节点
        ListNode*tmp_head=head;   //初始节点的前一个节点
        //找到初始节点
        for(int i=0;i<m;++i)    
        {
            tmp_head=head;
            head=head->next;
        }
        ListNode* p=head;
        ListNode* q=head->next;
        ListNode* r=q->next;
        //进行反转
        for(int i=m;i<n;++i)
        {
            q->next=p;
            p=q;
            q=r;
            if(r!=NULL) r=r->next;
        }
        //将反转后的部分嵌入链表
        if(head==tmp_head) result=p;    //m=1的情况
        else tmp_head->next=p;
        head->next=q;
        return result;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值