反转链表-用二重指针解决

反转链表-用二重指针解决

问题引入

输入一个链表,反转链表后,输出新链表的表头

题目:剑指offer-15.反转链表

一般情况下的解决办法

image-20210913235631899

用if处理特殊情况

  • head为空的情况
  • 只有一个节点的情况

用prev、curr、next来进行游走,维护链表

1 之前是这样的

ListNode* curr = head;
ListNode* prev = NULL;
ListNode* next = head->next;

image-20210914001311147

2 维护过程

while (next)
{
    curr->next = prev;
    prev = curr;
    curr = next;
    next = next->next;
}
curr->next = prev;

让curr用于调整指针,将当前节点的next指针从指向next,转变成指向prev

让next扮演“开路先锋”,一直走到“黑”

3 结果

链表被反转了

ListNode* ReverseList(ListNode* head) {
        /*链表少于一个节点*/
        if (!head||!head->next)
        {
            return head;
        }
        ListNode* curr = head;
        ListNode* prev = NULL;
        ListNode* next = head->next;
        while (next)
        {
            curr->next = prev;
            prev = curr;
            curr = next;
            next = next->next;
        }
        curr->next = prev;
        return curr;
    }

其实一般解法挺好理解的,就是用3个指针来维护链表。

二重指针

假设链表中每个节点都是

image-20210913234818369

它由NEXT字段和DATA字段组成

NEXT指向的是下一节点,本质上,NEXT字段存储了下一个节点的内存地址

所以 ListNode** curr = &head;这个二重指针,就是把头节点地址的指针的地址,存储在了curr里面。

点到为止,想详细了解二重指针和链表关系的,可参考之前我写的文章:

linus提到过的单链表删除节点算法 - wqybokeyuan - 博客园 (cnblogs.com)

最终代码:

ListNode* ReverseList(ListNode* pHead) {
        ListNode** curr = &pHead;
        ListNode* prev_1 = NULL;
        ListNode* prev_2 = NULL;
        while (*curr)
        {
            ListNode* temp = *curr;
            *curr = prev_2;
            prev_2 = prev_1;
            prev_1 = temp;
            curr = &(temp->next);
        }
        *curr = prev_2;
        return prev_1;
    }

用了1个curr二重指针和3个临时变量来维护链表,只是二重指针不需要用if判断是否为空,显得更牛逼一些罢了,其实本质上与上面的一般解法没啥区别~

做完题目,提交,一次性通过。这个奖杯,让我觉得很惊喜,很开心。大概这就是程序员的快乐吧 : )

image-20210913234220119

posted @ 2021-09-14 00:19  lucky_doog  阅读(111)  评论(0编辑  收藏  举报