這個題目我們需要考慮兩種情況: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;
}