#include <iostream>
#include <malloc.h>
using namespace std;
struct LinkNode{
int m_nValue;
LinkNode *next;
};
typedef LinkNode* LinkList;
void InsertList(LinkList &list , int data)//插入(建立)链表
{
LinkList head=list;
LinkList p=list;
LinkList q;
if(head==NULL)
{
head=(LinkList)malloc(sizeof(LinkNode));
head->m_nValue=data;
head->next=NULL;
list=head;
}
else
{
while(p->next)
p=p->next;
q=(LinkList)malloc(sizeof(LinkNode));
q->next=NULL;
q->m_nValue=data;
p->next=q;
}
}
//circlestart是环的起点,circlelen是环的长度,binglen是柄的长度
//一。快慢指针判断是否有环;
//二。如果有环,第一次相遇后,继续按照21的步长走,再次相遇时,循环的次数即为环长
//三。第二次相遇后,p指向链表头list,然后p和q都以步长为1继续走,直到p==q,走的步数即为柄长
//四。环长+柄长=链表节点数
bool isCircle(LinkList list, LinkList &circlestart, int &circlelen, int &binglen)//判断是否有环,如果有环,求出环的起点
{
LinkList p=list;
LinkList q=list;
while(p && q && p->next)
{
p=p->next->next;
q=q->next;
if(p==q)
break;
}
if(p==q)//有环
{
//求环长circlelen
circlelen=0;
while(p && q && p->next)
{
p=p->next->next;
q=q->next;
circlelen++;
if(p==q)
break;
}
//求环起点及柄长
binglen=0;
p=list;
while(p!=q)
{
p=p->next;
q=q->next;
binglen++;
}
circlestart=p;
return true;
}
else //无环
return false;
}
void main()
{
LinkList first=NULL;
LinkList startnode;
int circlelen=0;
int binglen=0;
InsertList(first,10);
InsertList(first,12);
InsertList(first,-11);
InsertList(first,45);
InsertList(first,23);
InsertList(first,75);
InsertList(first,66);
InsertList(first,82);
//无环
if(isCircle(first,startnode, circlelen, binglen))
cout<<"有环,起点是:"<<startnode->m_nValue<<"环长:"<<circlelen<<"柄长:"<<binglen<<endl;
else
cout<<"无环"<<endl;
//构造环,尾节点接到第三个节点前
LinkList p=first;
while(p->next)
p=p->next;
LinkList q=first;
for(int i=1; i<=2; i++)
q=q->next;
p->next=q;
if(isCircle(first,startnode,circlelen, binglen))
cout<<"有环,起点是:"<<startnode->m_nValue<<"环长:"<<circlelen<<"柄长:"<<binglen<<endl;
else
cout<<"无环"<<endl;
}
运行结果: