链表的中间结点
题目:
给你单链表的头结点
head
,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
示例 1:
输入:head = [1,2,3,4,5] 输出:[3,4,5] 解释:链表只有一个中间结点,值为 3 。示例 2:
输入:head = [1,2,3,4,5,6] 输出:[4,5,6] 解释:该链表有两个中间结点,值分别为 3 和 4 ,返回第二个结点。
思路:
使用 快慢指针(Fast-Slow Pointers) 来找到链表的中间节点,快慢指针
slow
:每次移动 1 步快指针fast
:每次移动 2 步。
代码:
struct ListNode* middleNode(struct ListNode* head)
{
if (head == NULL)
{
return NULL; // 处理空链表
}
struct ListNode* slow = head;
struct ListNode* fast = head;
// 快指针每次走2步,慢指针每次走1步
while (fast != NULL && fast->next != NULL)
{
slow = slow->next;
fast = fast->next->next;
}
return slow; // 慢指针指向中间节点
}
代码分析:
1. 快慢指针的初始化
慢指针
slow
:每次移动 1 步。快指针
fast
:每次移动 2 步。初始位置:两者都从链表头节点
head
开始。struct ListNode* slow = head; struct ListNode* fast = head;
2. 移动规则
循环条件:快指针能继续移动(即
fast
和fast->next
均不为空)。
这个条件是为了安全控制快指针的移动,确保在每次循环中能够安全访问 fast->next->next,避免空指针解引用导致的崩溃,防止 fast->next 为 NULL 时访问 fast->next->next。while (fast != NULL && fast->next != NULL)
每次迭代:
慢指针走 1 步:
slow = slow->next
。快指针走 2 步:
fast = fast->next->next
。3. 终止条件
当快指针无法继续移动时,慢指针指向中间节点:
链表长度为奇数:
fast
最终指向最后一个节点,slow
正好在中间。例:1 → 2 → 3 → 4 → 5
↑
slow链表长度为偶数:
fast
最终指向NULL
,slow
指向中间偏右的节点。例:1 → 2 → 3 → 4
↑
slow4. 返回结果
直接返回慢指针
slow
,此时它指向中间节点。return slow;