这段代码实现了一个单链表的反转功能,使用递归的方法。我们逐步分析这个代码中的每一步递归过程。
基本概念
- ListNode: 这是链表节点的结构体,通常包含两个成员:存储数据的值和指向下一个节点的指针(
next
)。 - head: 链表的头节点。
函数逻辑
基本情况:
if (head == NULL || head->next == NULL) { return head; }
- 如果
head
是NULL
或者只有一个节点(即head->next
是NULL
),那么这个链表已经是反转状态,直接返回该节点。
- 如果
递归调用:
ListNode* ret = reverseList(head->next);
- 这里将链表的下一个节点传入递归调用。也就是说,我们在不断地深入到链表末尾,直到到达最后一个节点。
反转指针:
head->next->next = head;
- 当我们从递归返回时,这一行执行的是关键操作。它把当前节点 (
head
) 的地址赋给head->next->next
,意思是让原来的下一个节点指向当前节点,从而实现了部分反转。
- 当我们从递归返回时,这一行执行的是关键操作。它把当前节点 (
断开原有链接:
head->next = NULL;
- 将当前节点的
next
指针设置为NULL
,因为现在它应该成为新链表的尾部,而不再指向旧的下一个节点。
- 将当前节点的
返回新的头结点:
return ret;
- 最后返回的是新的头结点,也就是原来链表中的最后一个节点,在所有递归层级结束后,它就成为了反转后的新头结点。
递归示例过程
假设我们有一个简单的链表: 1 -> 2 -> 3 -> 4 -> NULL
第一次调用:
- 输入:
1
- 执行:
reverseList(2)
- 输入:
第二次调用:
- 输入:
2
- 执行:
reverseList(3)
- 输入:
第三次调用:
- 输入:
3
- 执行:
reverseList(4)
- 输入:
第四次调用:
- 输入:
4
- 因为
4->next
为NULL
, 所以直接返回该节点 (即 新头结点)。
- 输入:
回溯过程
当开始回溯时:
从第四层返回到第三层 (
3
)- 设置:
然后:4.next = 3; // 原本是 null,现在变成指向3。
3.next = NULL; // 把现在3改为新尾部。
- 设置:
从第三层返回到第二层 (
2
)- 设置:
然后:3.next = 2; // 原本是 null,现在变成指向2。
2.next = NULL; // 把现在2改为新尾部。
- 设置:
从第二层返回到第一层 (
1
)- 设置:
然后:2.next = 1; // 原本是 null,现在变成指向1。
1.next = NULL; // 把现在1改为新尾部。
- 设置:
最终得到的新链表是:4 -> 3 -> 2 -> 1 -> NULL
总结:通过这种方式,每个函数调用负责翻转其相邻的一对元素,并通过递归逐步形成完整反转。
内容由零声教学AI助手提供,问题来源于学员提问