题目:判断判断链表是否相交,若相交返回交点(假设链表可能带环)
分析:根据题目画图,由题目可分解3中情况:
1.带环相交,交点不在环上
2.带环相交,交点在环上
3.不相交
设计函数:1.先判断两条链表是否相交
2.若相交,找出交点并把交点返回;
若不相交,返回NULL,结束函数。
3.找交点(可以分装一个函数):
(1)创建四个Node指针,L1指向链表1的头,L2指向链表2的头,pos1指向链表1的环入口点,pos2指向链表2的环入口点;
(2)如果在环外相交:将pos2->next=L2;然后调用判环函数IsCircle; 创建一个Node指针C接收C=IsCircle(p1);最后返回C。
(3)如果不在环外相交则就是再环上相交,返回环上的一个结点位置就好。
程序代码:
Node*JudgeCrossCircle(Node*list1,Node*list2) //14.判断判断链表是否相交,若相交返回交点(假设链表可能带环)
{
if (list1 == NULL)
return NULL;
if (list2 == NULL)
return NULL;
Node*Cross(Node*p1,Node*p2,Node*plist1,Node*plist2); //函数声明,下面求交点要用
Node*p1 = list1;
Node*p2 = list2;
Node*plist1 = IsCircle(list1); //若list1带环,plist1是其入口点
Node*plist2 = IsCircle(list2); //若list2带环,plist2是其入口点
Node*temp = plist1;
while (plist1!=temp->next)
{
if (temp == plist2) //链表list1与链表list2相交
{
Node*Meet = Cross(p1,p2,plist1,plist2); //求相遇点位置
return Meet;
}
temp = temp->next;
}
if (plist1 == plist2) //链表list1与链表list2相交
{
Node*Meet = Cross(p1,p2,plist1,plist2); //求相遇点位置
return Meet;
}
return NULL;
}
Node*Cross(Node*p1, Node*p2,Node*plist1,Node*plist2) //求相遇点位置
{
Node*L1 = p1; //链表1的头
Node*L2 = p2; //链表2的头
Node*pos1 = plist1; //链表1的环入口点
Node*pos2 = plist2; //链表2的环入口点
Node*C = NULL;
if (pos1 ==pos2) //在环外相交
{
plist2->next =p2; //将p2的尾结点与头结点相接
C = IsCircle(p1);
return C;
}
else //在环上相交
{
C = plist1->next; //将环上的一个点当做其交点
return C;
}
}
测试
int main()
{
Node*mylist1;
Init(&mylist1);
Pushback(&mylist1, 1);
Pushback(&mylist1, 2);
Pushback(&mylist1, 3);
Pushback(&mylist1, 4);
Pushback(&mylist1, 5);
Pushback(&mylist1, 6);
Pushback(&mylist1, 7);
Pushback(&mylist1, 8);
Node*ret = Find(mylist1, 8);
ret->next = Find(mylist1, 5);
Node*mylist2;
Init(&mylist2);
Pushback(&mylist2, 0);
Pushback(&mylist2, 11);
Pushback(&mylist2, 12);
Pushback(&mylist2, 13);
Node*temp = Find(mylist2, 13);
temp->next = Find(mylist1, 6); //换Find的的第二个参数,可测试三种情况
Node*Cross = JudgeCrossCircle(mylist1, mylist2);
/*cout << Cross->data << endl;*/ //当不相交的时候,屏蔽该行
system("pause");
return 0;
}
(1)环外相交
(2)换上相交
(3)不相交