单链表反转

来源:互联网 发布:爱丽丝门罗知乎 编辑:程序博客网 时间:2024/06/04 23:28

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

再接再厉吧!

链表结构体:

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
原创粉丝点击