判断两个链表是否相交,若相交,求交点。(假设链表不带环)
判断两个链表是否相交,若相交,求交点。(假设链表可能带环)
采用对齐的思想。计算两个链表的长度 L1 , L2,分别用两个指针 p1 , p2 指向两个链表的头,然后将较长链表的 p1(假设为 p1)向后移动L2 - L1个节点,然后再同时向后移动p1 , p2,直到 p1 = p2。相遇的点就是相交的第一个节点。
pNode CheckCircle(pList plist)//判断链表是否有环
{
assert(plist);
pNode fast = plist;
pNode slow = plist;
if (fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
if (fast == slow)
{
return slow;
}
}
return NULL;
}
int CircleLength(pList plist)//求环的长度
{
assert(plist);
pNode tmp = CheckCircle(plist);
pNode cur = CheckCircle(plist);
int count = 0;
do{
count++;
cur = cur->next;
} while (cur == tmp);
return count;
}
pNode FindNode(pList plist)//碰撞点
//碰撞点p到连接点的距离=头指针到连接点的距离,因此,分别从碰撞点、头指针开始走,相遇的那个点就是连接点。
{
pNode tmp = CheckCircle(plist);
pNode cur = pHead;
while (tmp != cur)
{
cur = cur->next;
tmp = tmp->next;
}
return tmp;
}
int CircleListLength(pList plist)//求环的长度
{
pNode cur = pHead;
pNode tmp = FindNode(plist);
int count = 0;
while (tmp != cur)
{
++count;
cur = cur->next;
}
return count + CircleLength(plist);
}
bool CheckNoCircleCross(pList plist1, pList plist2)//判断两个链表是否相交
{//判断两个链表的最后一个节点是否相同,如果相同,则相交
assert(plist1);
assert(plist2);
while (plist1->next)
{
plist1 = plist1->next;
}
while (plist2->next)
{
plist2 = plist2->next;
}
if (plist1 == plist2)
{
return true;
}
else
return false;
}
int ListLength(pList plist)
{
int count = 0;
while (plist)
{
++count;
plist = plist->next;
}
return count;
}
pNode FindNoCircleIntersectNode(pList plist1, pList plist2)//查找相交节点
{
int l1 = ListLength(plist1);
int l2 = ListLength(plist2);
if (l1 > l2)
{
for (int i = 0; i < l1 - l2; ++i)
{
plist1 = plist1->next;
}
}
else
{
for (int i = 0; i < l2 - l1; ++i)
{
plist2 = plist2->next;
}
}
while (plist1 != NULL)
{
if (plist1 == plist2)
{
return plist1;
}
plist1 = plist1->next;
plist2 = plist2->next;
}
return NULL;
}
pNode FindIntersectNode(pList plist1, pList plist2)// 查找交点(不知是否有环)
{
if ((!CheckCircle(plist1))&&(!CheckCircle(plist2)))
{
FindNoCircleIntersectNode(plist1, plist2);
}
if (CheckCircle(plist1) && (!CheckCircle(plist2)))
{
return NULL;
}
if (CheckCircle(plist2) && (!CheckCircle(plist1)))
{
return NULL;
}
int l1 = CircleListLength(plist1);
int l2 = CircleListLength(plist2);
if (l1 > l2)
{
for (int i = 0; i < l1 - l2; ++i)
{
plist1 = plist1->next;
}
}
if (l1 < l2)
{
for (int i = 0; i < l2 - l1; ++i)
{
plist2 = plist2->next;
}
}
while (plist1)
{
if (plist1 == plist2)
{
return plist1;
}
plist1 = plist1->next;
plist2 = plist2->next;
}
}


被折叠的 条评论
为什么被折叠?



