链表面试题之带环问题
2016-06-20
typedef int DataType;
typedef struct LinkNode
{
	DataType data;
	struct LinkNode *next;
}LinkNode,*pLinkNode;    
typedef struct LinkList
{
	LinkNode *phead;
}LinkList,*pLinkList; pLinkNode Check_Cycle(pLinkList plist)   //判断链表是否带环,若带环则返回相遇点
{
	pLinkNode fast=NULL;
	pLinkNode slow=NULL;
	assert(plist);
	fast=plist->phead;
	slow=plist->phead;
	while(fast && fast->next)
	{
		fast=fast->next->next;
		slow=slow->next;
		if(fast == slow)
		{
			return fast;
		}
	}
	return NULL;
}int Get_CircleLength(pLinkNode meet)     //求环的长度
{
	int count=1;
	pLinkNode cur=meet;
	pLinkNode pmeet=meet;
	while(cur->next != pmeet)
	{
		count++;
		cur=cur->next;
	}
	return count;
}pLinkNode GetCircle_EntryNode(pLinkList plist,pLinkNode meet)   //获取环的入口点
{
	pLinkNode front=plist->phead;
	pLinkNode back=meet;
	assert(plist);
	while(front != back)
	{
		front=front->next;
		back=back->next;
	}
	return front;
}void text7()
{
	int ptr=0;
	pLinkNode ret=NULL;
	pLinkNode meet=NULL;
	LinkList plist;
	Init_LinkList(&plist);
	Push_back(&plist,1);
	Push_back(&plist,2);
	Push_back(&plist,3);
	Push_back(&plist,4);
	Push_back(&plist,5);
	ret=Find_NUM(&plist,5);  //构造环
	ret->next=Find_NUM(&plist,3);
	meet=Check_Cycle(&plist);
	if(meet != NULL)
	{
		printf("带环链表的相遇结点为:%d\n",meet->data);
		ptr=Get_CircleLength(meet);
		printf("带环链表的环的长度为:%d\n",ptr);
		ret=GetCircle_EntryNode(&plist,meet);
		printf("带环链表的环的入口点为:%d\n",ret->data);
	}
	Free_LinkList(&plist);
}
int main()
{
	text7();
	system("pause");
	return 0;
}