这段代码的目的是反转一个单链表。下面是对代码逐行的详细解释,以及它运行时的步骤。
函数签名
ListNode* reverseList(ListNode* head)
这个函数接收一个指向链表头节点的指针 head
,并返回反转后的链表头节点。
步骤解析
检查空链表:
if (head == NULL) { return NULL; }
- 如果输入的链表头为
NULL
(表示链表为空),则直接返回NULL
。
- 如果输入的链表头为
初始化当前节点:
ListNode* cur = head;
- 创建一个指针
cur
,用于追踪已反转部分的最后一个节点。初始化为原始头节点head
。
- 创建一个指针
进入循环进行反转:
while (head->next != NULL) { ... }
- 这个循环会持续直到处理到最后一个节点。在每一次迭代中,我们要将当前节点和其下一个节点的链接方向进行修改,以实现反转。
保存下一个节点:
ListNode* t = head->next->next;
- 在修改链接之前,先保存当前节点的下一个节点(即
head->next
)的下一个位置。这样在后续操作中我们可以继续遍历未反转部分。
- 在修改链接之前,先保存当前节点的下一个节点(即
修改链接方向:
head->next->next = cur;
- 将当前
head
的下一个节点 (head->next
) 的下一步指向已反转部分的最后一个节点(即cur
)。这是实际改变链表结构的一步,使得原本指向前方的连接变成了指向后方。
- 将当前
更新当前已反转部分尾部:
cur = head->next;
- 更新
cur
指向新添加到已反转部分尾部的新末尾,即刚刚被调整方向的节点。
- 更新
移动到下一个待处理元素:
head->next = t;
- 将当前
head
移动到它原来位置上的下个未处理元素,这样就能继续下一次迭代。这里使用的是之前保存好的值t
,使得我们能够继续往下遍历未被处理过的部分。
- 将当前
返回新的头结点:
return cur;
- 当循环结束后,整个列表已经被完全反转,此时最新得到的新头结点是存储在变量
cur
中,因此返回这个新头结点即可。
- 当循环结束后,整个列表已经被完全反转,此时最新得到的新头结点是存储在变量
运行示例
假设输入链表为: 1 -> 2 -> 3 -> 4 -> NULL
初始状态:
- head: 1, cur: 1
第一次迭代:
- t = head->next->next; // t指向3
- head(1)->next(2)->next设置为cur(1);此时2变为指向1。
- cur更新为2。
- head更新为3。
第二次迭代:
- 类似地,重复上述步骤,使得最终结果完成了所有箭头方向都被逆置。经过几轮循环之后,你会得到:
结果输出: 4 -> 3 -> 2 -> 1 -> NULL
整个过程就是通过逐个改变每个 node 的 next 指针来实现完整链表翻转的方法。
内容由零声教学AI助手提供,问题来源于学员提问