16-反转链表

定义三个指针:
一个指向pre:
一个指向cur:
一个指向next:

因为反转链表后,第一个指向的下一个要为null,所以要把pre先设为null;
cur指向本节点,然后先保存下一个节点tempnext,因为如果cur的next指针要反向,反向后就找不到next节点了。然后把cur的next指向pre,pre更新为cur,cur更新为tempnext。
丑陋的代码:

ListNode* ReverseList(ListNode* pHead) {
        if (pHead == nullptr)
            return nullptr;
        if (pHead->next == nullptr)
            return pHead;
        ListNode* pre=nullptr;
        ListNode* cur = pHead;
        ListNode* res = nullptr;   //保存最后结果
        while (1)
        {
            ListNode* tempnext = cur->next;
            cur->next = pre;

            if (tempnext == nullptr)   //如果已经指向null了,那么就需要跳出了。
            {
                return res=cur;
            }
            pre = cur;
            cur = tempnext;

        }

    }

但是因为有时候会要求只是反转一部分,如图
这里写图片描述
为了使得上述代码能复用,需要改动一下:

ReverseList_part 表示只是反转部分,形参表示指向反转开始的头和尾;

ListNode* ReverseList_part(ListNode* pHead, ListNode* pEnd) 
{
    if (pHead == nullptr)
        return nullptr;
    ListNode* pre = nullptr;
    ListNode* cur = pHead;
    ListNode* res = nullptr;
    while (cur!=pEnd)    //这里的end是为空或者尾节点的下一个节点
    {
        ListNode* tempnext = cur->next;//最后一步时,tempnext 已经指向尾部的下一个(或空)
        cur->next = pre;       
        pre = cur;             //更新pre为cur (此时pre为最后一个节点)
        cur = tempnext;        //cur等于空或者尾节点下一个,下一步跳出循环
    }

    return pre;   //pre就是所求
}

上述代码的结果仅适用于截取一部分反转,我想着把这个稍微改一下用到那个例子中,但发现不行。。。主要是要记录两个指针的同时还要分别记录pHead的前一个和pEnd的后一个,还有当m=1时的特殊情况。。
下面是原题的代码:

ListNode *reverseBetween(ListNode *head, int m, int n)
{
    ListNode *addPreHead=new ListNode(-1); //新建一个头-头指针,比head还在前面
    addPreHead->next = head;
    ListNode *reshead = addPreHead;
    for (int j = 0; j < m-1;j++)
    {

        addPreHead = addPreHead->next;   //找到反转的前一个节点

    }

    ListNode* pre = nullptr;           //表示前一个节点
    ListNode* cur = addPreHead->next;  //表示当前节点
    ListNode* tail = cur;              //表示当前节点主要是方便最后把他的next指向反转部分的下一个节点
    for (int i = m; i <= n;i++)
    {
        ListNode* tempnext = cur->next;
        cur->next = pre;
        pre = cur;
        cur = tempnext;
    }

    addPreHead->next = pre;            //前一个节点指向反转后的链表头节点
    tail->next = cur;                  //链接后一个节点
    return reshead->next;              //返回头指针
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值