判断单链表是否有环

判断单链表是否有环?如何找到环的“起始”点?如何知道环的长度? 
 
相关题目: 
(1)找出单链表的倒数第 4个元素。找出单链表的中间元素。 

(2)判断两个单链表是否相交,若两个单链表相交,计算相交点。 

解题思路: 


(1)判断是否有环。采用快慢指针的思路,一个指针一次移动一个结点,另一个指针移动两个结
点。 

如果有环,则进入环后,快指针肯定可以追赶上慢指针,这样就会出现两者相等的情况,从而得出
有环,但有一个前提,这个单链表必须有一个以上的结点在环之外才能判断出入口地址。 


(2)怎么来找环的入口问题。 

假定环外的长度为 l,相遇时环入口距离相遇处距离为 a,整个环为 x,则有下面的公式。 
l + a = (l + a + nx )/2 即 l = nx – a。 

这样,让快指针从这个位置开始继续移动,但步进为 1,慢指针从链表头开始移动,下次相遇的位
置就是环的入口地址。 


(3)找环的长度。 
现在已经知道环的入口位置,这样的话,采用快慢指针,再次相遇时快指针多移动的距离就是环的
长度。


/*
说明:求环的入口地址
*/
int get_circle_local(Node *phead) 
{ 
	Node *fast = phead; 
	Node *slow = phead; 

	while(fast != NULL 
		&& fast->next != NULL) 
	{ 
		fast = fast->next->next; 
		slow = slow->next; 

		if(fast == slow) 
		{ 
			//slow指针指向链表头结点,fast指针仍在之前与slow相遇的地方
			slow = phead;
			while(slow!=fast) 
			{ 
				//slow,fast都改为走一步
				slow = slow->next; 
				fast = fast->next; 
			} 
			return slow->data;//data = local number 
		}  
	} 
	return 0; 
}
拓展知识

点击打开链接

判断两个链表是否相交:点击打开链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值