单链表交点问题的分类:
a.两个链表都无环
b.两个链表都有环(交点在环外;交点在环内)
下边给出图示:
注意:两个链表的交点处,并不仅仅是data域相等,还要有next域相同。
如果一个链表有环,另一个链表无环,他们是不可能有交点的。
反证:如果有交点,一个链表有环,另一个链表必然有环。不符合条件。
从以上可以看出,要想完全弄清楚这个交点问题,必须要判断,链表是否有环;链表的交
点。(关于链表是否有环,以及环的入口问题,在前边的文章中已有整理)
下边给出代码:
typedef struct LinkNode
{
DataType data;
struct LinkNode *next;
}LinkNode,*pLinkNode;
typedef struct LinkList
{
LinkNode *pHead;
}LinkList,*pLinkList;
pLinkNode CrossNoCircleNode(pLinkList plist1, pLinkList plist2)//两链表都无环
{
int len1 = 0;
int len2 = 0;
pLinkNode cur1 = plist1->pHead;
pLinkNode cur2 = plist2->pHead;
while (cur1)
{
len1++;
cur1 = cur1->next;
}
while (cur2)
{
len2++;
cur2 = cur2->next;
}
cur1 = plist1->pHead;
cur2 = plist2->pHead;
int d = len1 - len2;
if (d >= 0)
{
while (d--)
{
cur1 = cur1->next;
}
}
else
{
d = -d;
while (d--)
{
cur2 = cur2->next;
}
}
while (cur1 != cur2 &&cur1 && cur2)
{
cur1 = cur1->next;
cur2 = cur2->next;
}
if (cur1 != NULL && cur2 != NULL)
{
return cur1;
}
return NULL;
}
pLinkNode CrossCircleNode(pLinkList plist1, pLinkList plist2)//两链表有环
{
pLinkNode cur1 = plist1->pHead;
pLinkNode cur2 = plist2->pHead;
pLinkNode frontCrossNode1 = NULL;
pLinkNode frontCrossNode2 = NULL;
pLinkNode CrossNode = NULL;
//求出两个环的入口
frontCrossNode1 = firstCrossNode(plist1);
frontCrossNode2 = firstCrossNode(plist1);
if (frontCrossNode1->next == frontCrossNode2->next)//两环入口相同的情况
{
frontCrossNode2->next = cur2;
CrossNode = firstCrossNode(plist1);
return CrossNode;
}
else
{
while (cur2->next != frontCrossNode2)
{
if (frontCrossNode1 == cur2)
{
return frontCrossNode1;
}
cur2 = cur2->next;
}
return NULL;
}
}
pLinkNode CrossNode(pLinkList plist1, pLinkList plist2)
{
assert(plist1 && plist2);
pLinkNode ret = NULL;
if (plist1->pHead == NULL || plist2->pHead == NULL)
{
return NULL;
}
if (isCircle(plist1) == NULL && isCircle(plist2) == NULL)//两个链表都无环
{
//调用无环链表交点的函数
ret = CrossNoCircleNode(plist1,plist2);
return ret;
}
if (isCircle(plist1) && isCircle(plist2))//两个链表都带环
{
ret = CrossCircleNode(plist1,plist2);
return ret;
}
else
{
return NULL;
}
}