这个题目我们需要考虑两种情况:1.入环点为头节结,这个就是上一篇博客的题目,在这里不再多说。2.入环点不是头结点,如下图。
核心思路:多余部分到入环结点的长度=相遇点到入环结点的长度。
1.先定义一个快指针一个慢指针,找到该链表的相遇点。
2.快慢指针中的任意一个指针从相遇点出发,定义一个头指针从头结点出发,找到的公共节点就是入环结点。
代码实现
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
typedef struct SListNode
{
SLTDataType data;
struct SListNode *next;
}SListNode;
SListNode *detectCircle(SListNode *head)
{
//先判环,找两个节点,一个一次跳两次,一个一次跳一次
SListNode *fast = head;
SListNode *slow = head;
while (fast&&slow&&fast->next)//避免找不到fast的next的next
{
fast = fast->next->next;
slow = slow->next;
if (fast == slow)//找到相遇点,右对齐
{
break;
}
}
for (; fast&&fast->next; fast = fast->next,head = head->next)//两个节点中fast和head一起走,找到的公共节点就是环入口
{
if (fast->data == head->data)
{
return fast;
}
}
return NULL;
}
int main()
{
SListNode *phead;
SListNode *plast=NULL;
SListInit(&phead);
SListPushFront(&phead, 1);
plast = phead;
SListPushFront(&phead, 2);
SListPushFront(&phead, 3);
SListPushFront(&phead, 4);
plast->next = phead;
SListNode *ret = detectCircle(phead);
printf("%d", ret->data);
//SListPrint(phead);
system("pause");
return 0;
}