判断两链表是否相交,求交点(假设链表不带环)
判断两链表是否相交,求交点(假设链表可能带环)
RingEntry_Point()等函数见前篇.
SListNode* Intersect(SListNode *&L, SListNode *&M)//判断两链表是否相交,求交点(假设链表不带环)
{
//思路:若不带环,只有相交/不想交两种情况
// 与RingEntry_Point()函数方法相同:
// 求两个链表长度之差K,再令一个指针从长链表开始先走K步,令另一个指针从短链表头开始,
// 两链表一起走,相遇点就为入口点
if (L != NULL&&M != NULL)
{
SListNode *cur = L;
SListNode *NewNode = M;
int c1 = _LengthNode(cur);
int c2 = _LengthNode(NewNode);
int minus = _LengthNode(cur) - _LengthNode(NewNode);
if (minus > 0)
{
while (minus--)
{
cur = cur->next;
}
}
else
{
int tmp = -minus;
while (tmp--)
{
NewNode = NewNode->next;
}
}
while (NewNode != cur&&NewNode != NULL&&cur != NULL)
{
NewNode = NewNode->next;
cur = cur->next;
}
if (NewNode == NULL || cur == NULL)
return NULL;
return cur;
}
return NULL;
}
SListNode* IntersectRing(SListNode *&L, SListNode *&M)//判断两链表是否相交,求交点(假设链表可能带环)
{
//思路:考虑全部情况:1、不带环 相交/不相交 2、带环 一条带环一条不带环/两条都带环(其中又分交点不在环上/交点在环上)
//
//区分是哪一种情况,分别实现
if (L != NULL&&M != NULL)
{
if (!IsRing(L) && !IsRing(M))//不带环
return Intersect(L, M);
else if ((IsRing(L) && !IsRing(M)) || (!IsRing(L) && IsRing(M)))//一条带环一条不带环
return NULL;
else
{
//先求两链表的环入口点,若入口点一样,则为第5种情况否则是第4、6种情况
SListNode *re1 = RingEntry(L);
SListNode *re2 = RingEntry(M);
if (re1 == re2)//第5种情况 化为不带环相交链表问题
{
SListNode* m1 = IsRing(L);
SListNode*recover = m1->next;// 复原仿照RingEntry_Point()函数
m1->next = NULL;
SListNode*cur = Intersect(L, M);
m1->next = recover;
return cur;
}
else//第4、6种情况若其中一个环入口点在另一个环上,则为第6种情况,否则为第4种情况
{
SListNode *tmp = re1->next;
while (tmp != re1&&tmp != re2)
tmp = tmp->next;
if (tmp == re1)//第4种情况
return NULL;
printf("两链表带环,并且有两个交点\n");//第6种情况
SListNode *tmp1 = re1->next;
re1->next = NULL;
PrintNode(re1);
re1->next = tmp1;
return re2;
}
}
}
else
return NULL;
}
测试
void Test10()
{
printf("//Test10() Intersect() \n");
SListNode *LL = NULL;
PushBack(LL, 1);
PushBack(LL, 2);
PushBack(LL, 3);
PushBack(LL, 4);
PushBack(LL, 5);
PrintNode(LL);
SListNode *MM = NULL;
PushBack(MM, 1);
PushBack(MM, 2);
MM->next->next = LL->next->next->next;
PrintNode(MM);
SListNode *NN = NULL;
PushBack(NN, 7);
PushBack(NN, 8);
PushBack(NN, 9);
PushBack(NN, 0);
PrintNode(NN);
SListNode* c1 = Intersect(LL, MM);
SListNode* c2 = Intersect(LL, NN);
PrintNode(c1);
PrintNode(c2);
}
void Test11()
{
printf("//Test11() IntersectRing() \n");
SListNode *LL = NULL;
PushBack(LL, 1);
PushBack(LL, 2);
PushBack(LL, 3);
PushBack(LL, 4);
PushBack(LL, 5);
PrintNode(LL);
SListNode *NN = NULL;
PushBack(NN, 6);
PushBack(NN, 7);
PushBack(NN, 8);
PushBack(NN, 9);
PushBack(NN, 0);
PrintNode(NN);
SListNode* c1 = IntersectRing(LL, NN);//第1种
PrintNode(c1);
printf("\n");
SListNode *MM = NULL;//第2种
PushBack(MM, 0);
PushBack(MM, 1);
MM->next->next = LL->next;
SListNode* c2 = IntersectRing(LL, MM);
PrintNode(c2);
printf("\n");
Find(LL, 5)->next = Find(LL, 3);//第3种
SListNode* c3 = IntersectRing(LL, NN);
SListNode* c4 = IntersectRing(NN, LL);
PrintNode(c3);
PrintNode(c4);
printf("\n");
Find(NN, 0)->next = Find(NN, 8);//第4种
SListNode* c5 = IntersectRing(NN, LL);
PrintNode(c5);
printf("\n");
SListNode* c6 = IntersectRing(MM, LL);//第5种
SListNode* c7 = IntersectRing(LL, MM);
SListNode* tmp1 = c6->next;
c6->next = NULL;
PrintNode(c6);
c6->next = tmp1;
SListNode* tmp2 = c7->next;
c7->next = NULL;
PrintNode(c7);
c7->next = tmp2;
printf("\n");
Find(NN, 0)->next = Find(LL, 4);//第6种
SListNode* c9 = IntersectRing(NN, LL);
SListNode* tmp3 = c9->next;
c9->next = NULL;
PrintNode(c9);
c9->next = tmp3;
SListNode* c10 = IntersectRing(LL, NN);
SListNode* tmp4 = c10->next;
c10->next = NULL;
PrintNode(c10);
c10->next = tmp4;
printf("\n");
Find(LL, 5)->next = Find(LL, 1);//第6种
Find(NN, 0)->next = Find(LL, 4);
SListNode* c11 = IntersectRing(NN, LL);
SListNode* tmp5 = c11->next;
c11->next = NULL;
PrintNode(c11);
c11->next = tmp5;
SListNode* c12 = IntersectRing(LL, NN);
SListNode* tmp6 = c12->next;
c12->next = NULL;
PrintNode(c12);
c12->next = tmp6;
printf("\n");
}
转载于:https://blog.51cto.com/10739786/1737116