您的位置:首页 > Web前端

《剑指offer》:[37]如何得到链表环的入口地址

2016-06-19 15:49 447 查看
题目:如何得到链表环的入口结点

方案:分两步走:
第一步:先要找到链表中的环,得到环的结点的个数。可以设置两个指针一个走的比较快,一个比较慢,那么如果链表中存在一个环,那么这两个指针一定会陷入这个环中,快的指针一定会遇到慢的指针,所以很快就能遇到。因为前面有详细讲过,这里不再多介绍,给一张图吧。



第二步:得到环的个数以后,我们照样可以设置两个指针。第一个指针先前进N(N为环中结点的个数)步,然后和第二个指针以相同的速度前进,当它们相遇时的结点就是链表中环的入口。
具体过程如下图所示:



具体实现代码如下所示:
#include <iostream>
using namespace std;
struct  List
{
int data;
List *next;
};
int arr[7]={1,2,3,4,5,6,7};
List *pHead=NULL;
List *pNext=NULL;
List *pEnd=NULL;
bool InputInvalid=false;
void Listhelp(List **head,int data)
{
List *temp=new List ;
temp->data=data;
temp->next=NULL;
if(NULL==*head)
{
*head=temp;
pEnd=temp;
}
else
{
pEnd->next=temp;
pEnd=temp;
}
}
void CreateList(List **head,int *array,int length)
{
for(int i=0;i<length;i++)
Listhelp(head,array[i]);
//制造一个环;7->4
List *temp=*head;
while(temp->data!=4)
temp=temp->next;
pEnd->next=temp;
}
void show(List *head)
{
int count=0;
while(head)
{
cout<<head->data<<" ";
head=head->next;
count++;
if(count==15)
break;//有环所以用break退出;
}
}
int GetNumOfCircle(List *head)
{
int NodeCount=1;
if(NULL==head)
{
InputInvalid=true;
return 0;
}
List *pSlow=head->next;
if(pSlow==NULL)
{
InputInvalid=true;
return 0;
}
List *pFast=pSlow->next;// two steps;
while(pSlow!=NULL && pFast!=NULL)
{
if(pFast==pSlow)
break; //找到环;
pSlow=pSlow->next;
pFast=pFast->next;
if(pFast!=NULL)
pFast=pFast->next;
}
//计算环的个数;
while(pFast->next!=pSlow)
{
pFast=pFast->next;
NodeCount++;
}
return NodeCount;
}
//得到环的入口地址;
List *EntryNodeOfLoop(List *head,int count)
{
List *pNode1=head;
for(int i=0;i<count;i++)
pNode1=pNode1->next;
List *pNode2=head;
while(pNode1!=pNode2)
{
pNode1=pNode1->next;
pNode2=pNode2->next;
}
return pNode1;
}
int main()
{
int NodeCircle=0;
List *EnterNode=NULL;
CreateList(&pHead,arr,7);
cout<<"有环4567:";
show(pHead);
cout<<endl;
NodeCircle=GetNumOfCircle(pHead);
if(InputInvalid)
cout<<"THE INPUT IS INVALID@!"<<endl;
else
{
EnterNode=EntryNodeOfLoop(pHead,NodeCircle);
cout<<"环入口结点的值为:"<<EnterNode->data<<endl;
}
system("pause");
return 0;
}

运行结果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: