链表是否带环?环长?入口?时间复杂度?

【是否带环】

      基本思路:定义两个指针从头结点开始,一个一次向后走一步,一次走两步,循环,若能够走到NULL,则不带环,若走到两个指针相等,则带环。

代码如下:

pair<bool,PNode> HasCircle(PNode phead)//判断是否带环,带环的话环的长度,入口。
{
	assert(phead);                 //时间复杂度是O(n)
	PNode pcur = phead;
	PNode prev = pcur;
	int flag = 0;
	
	while (prev&&prev->_pNext)
	{
		pcur = pcur->_pNext;
		prev = prev->_pNext->_pNext;
		if (prev==pcur)
		{
				return make_pair(true,pcur);
		}
	}
	return make_pair(false,(PNode)NULL);
}

【环长】

       基本思路:判断完是否带环后,返回相遇位置,定义两个指针,一个整形count初始化为0,再从相遇位置开始,一个指针一次走一步,一个指针一次走两步,count++, 等到再次相遇时,返回count的值即为环长。

代码如下:

int LenOfCircle(PNode phead)//带环求环的长度 时间复杂度为O(n)
{
	pair<bool,PNode> res = HasCircle(phead);
	if (!res.first)
	{
		return 0;
	}
	PNode pcur = res.second;
	PNode prev = pcur;
	int count = 0;
	while(true)
	{
		pcur = pcur->_pNext;
		prev = prev->_pNext->_pNext;
		count++;
		if (prev == pcur)
		{
			return count;
		}
	}
}

【环的入口】

基本思路:

       第一次相遇时的位置知道后,则从头到入口的距离和相遇点到入口的距离相等(后有具体证明),则可以让一个指针从头开始走,一个指针从相遇点开始走,走到两个指针相遇,则相遇点就是入口点。

证明:(理科生,所以用公式来证明)

        求环长时,相遇点在5的地方,若pcur一步走两个,则pcur的路径为:l+R+h+R(也就是一圈然后在加上R),

prev的路径是:l+R,而这两个指针的路径又是有2倍的关系。

则:l+2R+h = 2*(l+R)

解上面的式子可以得到:l = h,也就是从头到入口的距离和从相遇点到入口的距离相等。


代码如下:

PNode EnterOfCircle(PNode phead)//带环求环的入口点//以及求时间复杂度O(n)
{
	pair<bool,PNode> res = HasCircle(phead);
	if (!res.first)
	{
		return 0;
	}
	PNode pcur = res.second;
	PNode prev = phead;
	while (true)
	{
		pcur = pcur->_pNext;
		prev = prev ->_pNext;
		if (prev == pcur)
		{
			return pcur;
		}
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值