ZBLOG

ListNode* reverseList(ListNode* head) { if (head == NULL || head->next == NULL) { return head; } ListNode* ret = reverseList(head->next); head->next->next = head; head->next = NULL; retur...

这段代码实现了一个单链表的反转功能,使用递归的方法。我们逐步分析这个代码中的每一步递归过程。

基本概念

  • ListNode: 这是链表节点的结构体,通常包含两个成员:存储数据的值和指向下一个节点的指针(next)。
  • head: 链表的头节点。

函数逻辑

  1. 基本情况:

    if (head == NULL || head->next == NULL) {
       return head;
    }
    
    • 如果 headNULL 或者只有一个节点(即 head->nextNULL),那么这个链表已经是反转状态,直接返回该节点。
  2. 递归调用:

    ListNode* ret = reverseList(head->next);
    
    • 这里将链表的下一个节点传入递归调用。也就是说,我们在不断地深入到链表末尾,直到到达最后一个节点。
  3. 反转指针:

    head->next->next = head;
    
    • 当我们从递归返回时,这一行执行的是关键操作。它把当前节点 (head) 的地址赋给 head->next->next,意思是让原来的下一个节点指向当前节点,从而实现了部分反转。
  4. 断开原有链接:

    head->next = NULL;
    
    • 将当前节点的 next 指针设置为 NULL,因为现在它应该成为新链表的尾部,而不再指向旧的下一个节点。
  5. 返回新的头结点:

    return ret;
    
    • 最后返回的是新的头结点,也就是原来链表中的最后一个节点,在所有递归层级结束后,它就成为了反转后的新头结点。

递归示例过程

假设我们有一个简单的链表: 1 -> 2 -> 3 -> 4 -> NULL

  • 第一次调用:

    • 输入: 1
    • 执行:reverseList(2)
  • 第二次调用:

    • 输入: 2
    • 执行:reverseList(3)
  • 第三次调用:

    • 输入: 3
    • 执行:reverseList(4)
  • 第四次调用:

    • 输入: 4
    • 因为 4->nextNULL, 所以直接返回该节点 (即 新头结点)。

回溯过程

当开始回溯时:

  1. 从第四层返回到第三层 (3)

    • 设置:
      
      4.next = 3; // 原本是 null,现在变成指向3。
      
      然后:
      
      3.next = NULL; // 把现在3改为新尾部。
      
  2. 从第三层返回到第二层 (2)

    • 设置:
      
      3.next = 2; // 原本是 null,现在变成指向2。
      
      然后:
      
      2.next = NULL; // 把现在2改为新尾部。
      
  3. 从第二层返回到第一层 (1)

    • 设置:
      
      2.next = 1; // 原本是 null,现在变成指向1。
      
      然后:
      
      1.next = NULL; // 把现在1改为新尾部。
      

最终得到的新链表是:4 -> 3 -> 2 -> 1 -> NULL

总结:通过这种方式,每个函数调用负责翻转其相邻的一对元素,并通过递归逐步形成完整反转。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=20465

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?