判断一个链表是否有环

1、判断链表是否有环
2、得到环的长度
3、得到环的入口节点

设置两个指针,让一个前进速度快,一个前进速度慢,当两者相遇就说明链表存在环
环的长度由第一次两指针相遇到第二次两指针相遇所循环的次数得出
环的入口节点怎么得出需要证明:假设速度快的节点fast每次走两步用,慢的节点slow每次走一步;
它们俩第一次相遇时fast走了2s步,slow走了s步,入口节点到头节点的距离是a,环长r,a+r为L;
第一次相遇时2s=s+nr;即s=nr,继而推出s=(n-1)r+(L-a);并且由于是第一次相遇,可以推出
slow并没有走完一次环(因为在slow到达环时fast就已经在环内了,fast能追上slow),所以设slow
在环内走了x步,则a+x=(n-1)r+(L-a);a=(n-1)r+(L-a-x);即a的长度等于(n-1)个环的
长度加上第一次相遇时slow没走完的环的剩余长度。所以当两个指针一个从链表的头开始走,一个从slow开始走,两者相遇的时候该节点就是环的入口节点。

#include <iostream>
using namespace std;

typedef struct node
{
	int x;
	node *next;
}list;

bool isLoop(list *a);
int LpLength(list *a);
list *LoopEntrance(list *a);

int main(int argc, char *argv[])
{


	return 0;
}

bool isLoop(list *a)		//判断是否存在环
{
	list *fast = a;
	list *slow = a;
	while (fast != NULL && fast->next != NULL)
	{
		fast = fast->next->next;
		slow = slow->next;
		if (fast == slow)
			return true;
	}
	return false;
}

int LpLength(list *a)			//得到环的长度
{
	if (!isLoop(a))
		return 0;
	list *fast = a;
	list *slow = a;
	int flag = 0;
	int length = 0;
	while (fast != NULL && fast->next != NULL)
	{
		fast = fast->next->next;
		slow = slow->next;
		if (fast == slow)
			flag++;
		if (flag == 1)
			length++;
		if (flag == 2)
			break;
	}
	return length;
}

list *LoopEntrance(list *a)			//得到环的入口节点地址
{
	if (!isLoop(a))
		return NULL;
	list *fast = a;
	list *slow = a;
	while (fast != NULL & fast->next != NULL)
	{
		fast = fast->next->next;
		slow = slow->next;
		if (fast == slow)
			break;
	}
	slow = a;
	while (slow != fast)
	{
		slow = slow->next;
		fast = fast->next;
	}
	return slow;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值