判断链表是否有环并找到进入环的那个结点

本文介绍了一种高效判断链表是否存在环的方法,并详细解析了如何找到链表入环的第一个节点。通过快慢指针技巧,不仅能够检测链表是否形成闭环,还能精确定位入环点,为链表相关算法问题提供了实用解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

判断链表是否有环并找到进入环的那个结点

单链表的三种情况:
1,尾结点接到头结点上 (循环链表)
2,尾结点接到链表中间(数字6形状)
3,无环,存在结点指向null

思想:定义两个指针,fast指针跑的速度是slow的二倍。
1,如果两指针相遇,那么就有环(有环的话,他们两都会一直在环里跑,而fast的速度是slow的两倍,所以会相遇)
2,如果fast指针不跑了,说明遇到了null,即表示没有环。

typedef int ElemType;

typedef struct _Node
{
	ElemType data;
	struct _Node *next;
}LNode, *LinkList;

static LinkList Have_Ring(LinkList list)
{
	LinkList fast = list->next;
	LinkList slow = list;
	while (fast)
	{
		if (fast == slow)   return fast;
		else
		{
			if ((fast->next)==NULL)   return NULL ;
			else
			{
				fast = fast->next->next;
				slow = slow->next;
			}
		}
	}
	return NULL;
}

这个还是比较好理解的~因为后面推导环开始的位置需要用到两指针相遇的地方,所以我们这里用返回指针的函数。


找到入环的结点
假设两个指针在下图所示位置相遇;
在这里插入图片描述
我们在上面定义两个指针的时候,fast的指针的速度是slow指针的两倍,在两指针相遇的时候,花费时间是相同的。
所以我可以的得到以下等式
2(x+y)=x+y+n(z+y)
化解:
x=(n-1)(y+z)+z
这个式子也可以写成:
x=n(y+z)+z
(因为在数学角度,n和n-1是没多大区别的,区别在于你n取多少值)
那么这个式子是什么意思呢?
我们再设立两个指针(p和q),一个(p)放在头结点的位置,一个(q)放在fast和slow相遇的结点;
两个指针同时开始走,速度相同,那么当这两个指针相遇的时候,处于的结点位置就是入环的结点。
可能q会围绕着环转很多圈,也有可能第一次到入环结点的时候,就和p相遇了。
这里不用考虑p指针入环,还和q指针没有相遇的情况,由于我们得到的那个式子,所以这个情况是不可能存在

具体实现如下:

int Find_Entrynode(LinkList list)
{
	LinkList p = list ->next;
	LinkList q = Have_Ring(list);
	int count=0;      //用于表示入环结点的位置
	while(p!=q)
	{
		p = p->next;
		q = q->next;
		count++;
	 } 
	 return count;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值