标签:
1.第一种实现
bool List_is_loop(slist *head)
{
slist *slow=head;
slist *fast=head;
while(NULL!=fast && NULL!=fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast) break;
}
// 无环:当链表个数为基数时fast->next总是为NULL;当链表个数为偶数时fast总是为NULL;
return !(fast==NULL || fast->next==NULL);
}
2.第二种实现
bool List_is_loop(slist *head)
{
slist *slow=head;
slist *fast=head;
if( NULL==slow || NULL==slow->next)
return false;
do
{
slow=slow->next;
fast=fast->next->next;
}while(NULL!=fast && NULL!=fast->next && slow!=fast)
if(slow==fast)
{
return true;
}
else
{
return false;
}
}
3. 若链表存在环,找到环的入口点
假设 slow走了s步,则fast走了2s步(fast的步数还等于s加上在环上多转的n圈),设环长为r,则:
2s=s+nr
s=nr
设整个链表长L,入口环与相遇点距离为x,起点到环入口点的距离为a,则
a+x=s=nr
a+x=(n-1)r+r=(n-1)r+L-a
a=(n-1)r+(L-a-x)
(L-a-x)为相遇点到环入口点的距离。由此可知,从链表头到环入口点等于(n-1)循环内环+相遇点到环入口点。于是可以从链表头和相遇点分别设一个
指针,每次各走一步,两个指针必定相遇,且相遇第一点为环入口点。
1---2---3---4--5--6--7
| |
-----------
如上图所示:在节点5相遇;1到4的距离为a;4到5的距离为x;环长度为r;
slist* List_is_loop_enter(slist *head)
{
slist *slow=head;
slist *fast=head;
while(NULL!=fast && NULL!=fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast) break;
}
// 无环:当链表个数为基数时fast->next总是为NULL;当链表个数为偶数时fast总是为NULL;
if(fast==NULL || fast->next==NULL)
return NULL;
slow=head;
while( slow!=fast)
{
slow=slow->next;
fast=fast->next;
}
return slow;
}
4.计算环长度
从环入口进行一个循环即可。
int List_is_loop_length(slist *head)
{
int length=0;
slist *slow=head;
slist *fast=head;
while(NULL!=fast && NULL!=fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast) break;
}
// 无环:当链表个数为基数时fast->next总是为NULL;当链表个数为偶数时fast总是为NULL;
if(fast==NULL || fast->next==NULL)
return 0;
slow=head;
while( slow!=fast)
{
slow=slow->next;
fast=fast->next;
}
//从环入口开始循环
slist* p=slow;
do
{
p=p->next;
length++;
}while(p!=slow)
return length;
}
标签:
原文地址:http://www.cnblogs.com/hj-blog/p/4430218.html