通过Leetcode 206 反转链表理解递归(C++ 迭代、递归实现)

本文详细介绍了如何使用C++的迭代和递归方法解决LeetCode 206题——反转链表。在迭代解法中,通过两个指针pre和cur协同操作实现。而在递归解法中,阐述了递归条件和终止条件,并用工作分解的例子帮助理解递归过程。最后提供了代码实现,并特别注意了递归终止条件和特殊情况的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
迭代解法

思路: 定义两个指针,分别指向两个相邻的结点,pre指针指向较前的那个结点,cur指针指向较后的那个结点,每次将cur->next更新为pre即可。

注意事项: 由于链表不支持随机访问,只有通过上一个结点的next指针才能访问当前结点,再通过当前结点的next指针才能访问下一个结点,所以如果仅修改cur的next指针,就丢掉了cur后面结点的索引,就无法继续处理后续的结点了。

解决方法 : 在修改cur的next指针前,让一个新的变量记录一下cur的下一个结点,这样处理就不会丢失cur之后的结点了。

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *pre=NULL,*cur=head;
        while(cur != NULL){ //当cur指针不为空时
            ListNode *next=cur->next;
            cur->next=pre;
            pre=cur;
            cur=next;
        }
        return pre;
    }
};

递归解法:

递归条件:
翻转以head为头结点的链表,首先需要得到翻转完成的以head->next为头结点的子链表,要得到以head->next为头结点的子链表,首先需要得到翻转完成的以head->next->next为头节点的子链表…一直这样递归下去,直到遇到终止条件。

终止条件
当到达最后一个结点时,由于最后一个结点之后不存在子链表了,所以不会往下继续递归了,此时开始逐层返回。返回的同时处理指针指向。

逐层返回时,指针的处理方法:

假设当前结点为head,head结点之后的结点已经翻转完毕了,现在就剩先head结点没有翻转了,所以在本次返回中,只要处理一下head结点的翻转就好了,即:将已经反转好的子链表头节点的next指针指向head结点,head的next指向NULL,然后就完成了整个链表的翻转。如图:

在这里插入图片描述

我对递归的理解是:

比如一项工作需要ABC共同完成,我和A说:你帮我完成一下这个工作,于是A对B说:你帮我完成一下这个工作,没有你B的工作成果,我A没办法开始,于是B对C说:你帮我完成一下这个工作,没有你C的工作成果,我B没办法开始。由于C的工作可以直接开始,不需要等待别的工作成果才能开始,所以任务被传达到了C之后,C开始工作,完成了之后将工作成果交给B,此时B可以工作了,完成之后将工作成果交给A,于是A开始工作,A完成之后,整个任务就圆满结束了。

代码实现:

//递归解法

class Solution {
public:
    ListNode* reverseList(ListNode* head) {

        if(head == NULL || head->next == NULL) return head;

        ListNode* p=reverseList(head->next);
        head->next->next=head;
        head->next=NULL;
        return p;
    }
};

注:判断条件中:

  • head->next == NULL是递归终止条件
  • head == NULL是处理特殊情况,如果传入的链表是NULL,则直接返回NULL,如果不处理就会产生空指针异常的错误。因为head为空,再取head->next就会出错。

注:这里的ListNode* p保存的就是新链表的头,在整个返回过程中,P指向的链表一直在发生变化,但是P的值一直没有改变,等到返回到最顶层之后,也就是任务的最开始时,P指向的链表就是整个反转后的链表。

递归的具体细节:
在这里插入图片描述

呼~,我终于班门弄斧一回了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值