数据结构--给定一个链表,返回链表开始入环的第一个节点,无环返回NULL

这个题目我们需要考虑两种情况: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;
}
发布了50 篇原创文章 · 获赞 30 · 访问量 9178

猜你喜欢

转载自blog.csdn.net/qq_42913794/article/details/100562468
今日推荐