链表面试题之链表相交问题
链表相交问题,面试题,链式表2016-06-26
int Check_Cross(pLinkList plist1,pLinkList plist2)
{
//判断链表是否相交,两个链表均不带环
pLinkNode p1=plist1->phead;
pLinkNode p2=plist2->phead;
if((p1 == NULL)||(p2 == NULL)) //空链表
{
return -1;
}
while(p1->next)
{
p1=p1->next;
}
while(p2->next)
{
p2=p2->next;
}
//p1,p2分别指向链表plist1,plist2的最后一个结点
//通过判断最后一个结点是否相同来判断两条链表是否相交
if(p1 == p2)
return 1; //相交
return 0;
}
pLinkNode GetLink_EntryNode(pLinkList plist1,pLinkList plist2)
{
//统计出两个链表的结点总数count1,count2
//让较长的链表走count1-count2步
//两个链表一起走直到相遇则返回相遇结点的地址
int count1=0;
int count2=0;
pLinkNode cur1=NULL;
pLinkNode cur2=NULL;
assert(plist1);
assert(plist2);
cur1=plist1->phead;
cur2=plist2->phead;
while(cur1) //统计链表1的总结点数
{
count1++;
cur1=cur1->next;
}
while(cur2) //统计链表2的总结点数
{
count2++;
cur2=cur2->next;
}
cur1=plist1->phead;
cur2=plist2->phead;
if(count1-count2 >= 0)
{
while(count1-count2 != 0)
{
cur1=cur1->next;
count1--;
}
if(cur1 != cur2)
{
cur1=cur1->next;
cur2=cur2->next;
}
}
else
{
while(count2-count1 != 0)
{
cur2=cur2->next;
count2--;
}
if(cur1 != cur2)
{
cur1=cur1->next;
cur2=cur2->next;
}
}
return cur1;
}
pLinkNode _GetLink_EntryNode(pLinkList plist1,pLinkList plist2)
{
//构造成环的方法求两个链表的交点
pLinkNode meet=NULL;
pLinkNode cur=NULL;
assert(plist1);
assert(plist2);
cur=plist1->phead;
//构造环
while(cur->next)
{
cur=cur->next;
}
cur->next=plist2->phead;
//找出环的相遇结点
meet=Check_Cycle(plist1);
//求出环的入口点
return GetCircle_EntryNode(plist1,meet);
}int _Check_Cross(pLinkNode meet1,pLinkNode meet2)
//两条链表都带环判断链表是否相交
{
pLinkNode m1=meet1;
pLinkNode m2=meet2;
while(m1 != m2)
{
m1=m1->next;
}
if(m1 == m2)
return 1;//链表相交
return 0;
}
pLinkNode EntryNode(pLinkList plist1,pLinkList plist2,pLinkNode start1)
{
pLinkNode s=start1;
pLinkNode meet=NULL;
assert(plist1);
assert(plist2);
while(s->next != start1)
{
s=s->next;
}
s->next=plist2->phead;
meet=Check_Cycle(plist1);
return GetCircle_EntryNode(plist1,meet);
}void text10()
{
int ret=0;
LinkList plist1;
LinkList plist2;
pLinkNode meet1=NULL;
pLinkNode meet2=NULL;
pLinkNode start1=NULL;
pLinkNode start2=NULL;
pLinkNode tmp=NULL;
Init_LinkList(&plist1);
Push_back(&plist1,1);
Push_back(&plist1,3);
Push_back(&plist1,5);
Push_back(&plist1,7);
Push_back(&plist1,9);
Push_back(&plist1,11);
Find_NUM(&plist1,11)->next=Find_NUM(&plist1,5); //链表1构造成环
Init_LinkList(&plist2);
Push_back(&plist2,2);
Push_back(&plist2,4);
//Find_NUM(&plist2,4)->next=Find_NUM(&plist1,7); //交点在环内
Find_NUM(&plist2,4)->next=Find_NUM(&plist1,3); //交点在环外
//1
//Init_LinkList(&plist1); //两条链表都不带环
//Push_back(&plist1,9);
//Push_back(&plist1,1);
//Push_back(&plist1,3);
//Push_back(&plist1,5);
//Push_back(&plist1,7);
//printf("链表1的元素为:");
//Print_LinkList(&plist1);
//2
//Init_LinkList(&plist2);
//Push_back(&plist2,2);
//链表2与链表1公用同交点以后的结点
//Find_NUM(&plist2,2)->next=Find_NUM(&plist1,3);
//printf("链表2的元素为:");
//Print_LinkList(&plist2);
meet1=Check_Cycle(&plist1);
meet2=Check_Cycle(&plist2);
if(meet1 == NULL && meet2 == NULL)
{
//两条链表都不带环
ret=Check_Cross(&plist1,&plist2);
if(ret == 1)
{
printf("两个链表相交\n");
//tmp=GetLink_EntryNode(&plist1,&plist2);
tmp=_GetLink_EntryNode(&plist1,&plist2);
printf("链表的相交点为:%d\n",tmp->data);
}
else if(ret == 0)
{
printf("两个链表不相交\n");
}
else
{
printf("存在空链表\n");
}
}
else if((meet1 == NULL && meet2 != NULL) || (meet1 != NULL && meet2 == NULL))
{
//一条链表带环一条链表不带环
printf("两个链表不相交\n");
}
else
{
//两条链表都带环
ret=_Check_Cross(meet1,meet2);
if(ret == 1)
{
printf("两个链表相交\n");
start1=GetCircle_EntryNode(&plist1,meet1);
start2=GetCircle_EntryNode(&plist2,meet2);
if(start1 == start2) //交点在环外
{
tmp=EntryNode(&plist1,&plist2,start1);
printf("链表的相交点为:%d\n",tmp->data);
}
else //交点在环内
{
printf("链表的相交点为:%d\n",start2->data);
}
}
else
{
printf("两个链表不相交\n");
}
}
free(meet1);
free(meet2);
}