35. 反转链表

题目

定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。

思考题:

请同时实现迭代版本和递归版本。
数据范围
链表长度 [0,30]。

样例
输入:1->2->3->4->5->NULL

输出:5->4->3->2->1->NULL

迭代版代码一

在这里插入图片描述

从第一个节点和第二个节点开始遍历到尾节点的后一个节点,最开始时前驱指针指向链表的第一个节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(!head || !head->next) return head;//如果链表为空或者只有一个节点,则不需要反转
        ListNode* a = head, *b = head->next;//a为第一个节点,b为第二个节点
        while(b){//等价于a->next
            auto c = b->next;//临时保存b的下一个节点
            b->next = a;//b的next指针指向a
            a = b, b = c;//a和b往后移动一个节点
        }
        head->next = NULL;//给反转后的尾节点的next指针置为NULL;
        return a;//a此时为反转后的头节点
    }
};

迭代版代码二

从头节点开始遍历到尾节点,最开始时前驱指针指向为null

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode * pre = nullptr;
        ListNode * cur = head;
        while(cur){//当cur遍历到链表尾
            auto next = cur->next;//临时保存cur的下一个节点地址
            cur->next = pre;//更新当前节点的指向
            pre = cur;//前驱节点移动到当前节点
            cur = next;//当前节点移动到cur的下一个节点
        }
        return pre;//返回原链表尾节点的前驱节点,即反转链表后的头节点
    }
};

递归版代码

  • 关键是利用递归结束条件,控制最深层递归是在尾节点return尾节点地址
  • 因为递归的参数为head->next,所以当即5->next==null满足递归结束条件head->next == null退出到上一层递归时,,head为尾节点5的前驱节点4
  • 再执行两行修改节点指针的关键代码
    • head->next->next = head;目的是通过访问head节点4,修改节点4的后继节点5的next指针指向节点4
    • head->next = null;目的是让当前head节点4指向空
  • 因为前面调用递归函数的返回值一直是最深层递归退出时的head->next==null,即原链表的尾节点,一直没有发生变化
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(!head || !head->next)return head;//如果链表为空,或者满足递归结束条件head->next==null
        auto res = reverseList(head->next);//保存返回最终链表的头节点,返回值一直都是最终链表的头节点
        head->next->next = head;//当最深一层递归退出时,即5->next == null时退出,递归结束条件直接返回head,即res = head==5
                                //此时返回到上一层的递归时的head为4,此行代码的目的是让5的next指针指向4
        head->next = nullptr;//让当前节点指向空
        return res;//返回一直保存的最终链表的头节点,即head==5
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值