单链表相交分为三种情况。
- 两个链表相交且都不带环
//单链表相交1
Node* IsCross_NoCycle(List list1, List list2)
{
assert(list1 && list2);
int len1 = length(list1);
int len2 = length(list2);
Node* longlist;
Node* shortlist;
int gap = 0;
if (len1 > len2)
{
longlist = list1;
shortlist = list2;
gap = len1 - len2;
}
else
{
longlist = list2;
shortlist = list1;
gap = len2 - len1;
}
while (gap--)
{
longlist = longlist->next;
}
//一起走
while (longlist != shortlist)
{
longlist = longlist->next;
shortlist = shortlist->next;
}
if (longlist != shortlist)
{
return false;
}
else {
return longlist;
}
}
test
int main()
{
Node head1;
InitList(&head1);
tailInsert(&head1, 1);
tailInsert(&head1, 2);
tailInsert(&head1, 3);
Show(&head1);
Node head2;
InitList(&head2);
tailInsert(&head2, 4);
tailInsert(&head2, 5);
tailInsert(&head2, 6);
tailInsert(&head2, 111);
tailInsert(&head2, 8);
tailInsert(&head2, 9);
Show(&head2);
Node *cross = Find(&head2, 8);
Node *tail = Find(&head1, 3);
tail->next->next = cross;
Show(&head1);
printf("交点是:%d\n", IsCross_NoCycle(&head1, &head2)->data);
return 0;
}
- 当链表一个有环一个无环时
- 当两个链表都有环时
Node* IsCross_Cycle(List list1, List list2)
{
assert(list1 && list2);
//求链表带环的相遇点
Node* MeetNode1 = Circle(list1);//返回环的入口
Node* MeetNode2 = Circle(list2);
Node* entry1;
Node* entry2;
Node* meet, *cur1;
//判断链表是否带环
if (MeetNode1 == NULL || MeetNode2 == NULL)
return NULL;//其中一个链表不带环,则不会相交,返回NULL
//两个链表都带环,相交的两种情况
//1.相同的入口点 2.不同的入口点
entry1 = GetEntry(list1, MeetNode1);
entry2 = GetEntry(list2, MeetNode2);
if (entry1 == entry2)//相同的入口点,返回交点
{
//entry1->next = NULL;
//entry2->next = NULL;
meet = IsCross_NoCycle(list1, list2);
return meet;
}
//不同的入口点的情况
//判断条件:从MeetNode1开始遍历链表,如果找到和MeetNode2相等的节点,则证明共用环
//如果相交,返回任意一个入口点
cur1 = MeetNode1->next;
while (cur1 != MeetNode1 && cur1 != MeetNode2)
{
cur1 = cur1->next;
}
if (cur1 == MeetNode2)
return entry1;
return NULL;//不相交
}
test
int main()
{
Node head1;
InitList(&head1);
tailInsert(&head1, 1);
tailInsert(&head1, 2);
tailInsert(&head1, 3);
Show(&head1);
Node head2;
InitList(&head2);
tailInsert(&head2, 4);
tailInsert(&head2, 5);
tailInsert(&head2, 6);
tailInsert(&head2, 7);
tailInsert(&head2, 8);
tailInsert(&head2, 9);
tailInsert(&head2, 10);
tailInsert(&head2, 11);
Show(&head2);
Node *cross = Find(&head2, 8);
Node *tail1 = Find(&head1, 3);
tail1->next->next = cross;
Node *tail2 = Find(&head2, 11);
Node *entry = Find(&head2, 9);//入口点
tail2->next->next = entry;//带环
printf("交点是:%d\n", IsCross_Cycle(&head1, &head2)->data);
return 0;
}