1.假设链表不带环:
判断是否相交:如果两个链表不带环,那么如果它们相交,情况一定是这样的:
那么它们的尾节点一定是相同的,那么利用这点来写代码:
int InterList(ListNode* list1,ListNode* list2)//是否相交
{
ListNode* cur1 = list1;
ListNode* cur2 = list2;
while(cur1->next || cur2->next) //让两个走到尾
{
if(cur1->next)
{
cur1 = cur1->next;
}
if(cur2->next)
{
cur2 = cur2->next;
}
if(cur1 == cur2) //走到尾相等,那有交点
{
return 1;//有交点,返回1
}
}
return 0;
}
求交点:先求两个链接的长度差,让长的链表从往后走长度差的节点,然后两个一起走,直到两节点相等,那么此节点为交点:
int DifferenceValue(int num1,int num2)//返回长度差
{
int rent = 0;
if(num1 > num2)
{
rent = num1-num2;
}
else
{
rent = num2-num1;
}
return rent;
}
ListNode* GetCrossNode(ListNode* list1,ListNode* list2)//求交点
{
ListNode* cur1 = list1;
ListNode* cur2 = list2;
ListNode* longlist = list1;
ListNode* shortlist = list2;
int sz1 = 0;
int sz2 = 0;
int rent = 0;
while(cur1)//求链表有几个节点
{
cur1 = cur1->next;
sz1++;
}
while(cur2)//求链表有几个节点
{
cur2 = cur2->next;
sz2++;
}
if(sz1<sz2)//把长链表给longlist,短的给shortlist
{
longlist = list2;
shortlist = list1;
}
rent = DifferenceValue(sz1,sz2);
while(rent--)//长链表先走rent个节点
{
longlist = longlist->next;
}
while(longlist != shortlist)
{
longlist = longlist->next;
shortlist = shortlist->next;
}
return shortlist;
}
2.假设链表可能带环:只分析
一个带环,一个不带环:
两个都带环:
环外相交:
环内相交:
给出环内相交的代码:
ListNode* CircleGetCrossNode(ListNode* list1,ListNode* list2)
{
ListNode* cur1 = EntryPointRing(list1);
ListNode* cur2 = EntryPointRing(list2);
ListNode* meet = cur1;
while(meet->next != cur1)
{
meet = meet->next;
if(meet == cur2)
{
return cur2;
}
}
return NULL;
}
测试:
void ListTest12()
{
ListNode* list1 = NULL;
ListNode* list2 = NULL;
ListNode* tail1 = NULL;
ListNode* tail2 = NULL;
ListNode* ret = NULL;
PushBack(&list1,1);
PushBack(&list1,2);
PushBack(&list1,3);
PushBack(&list1,4);
PushBack(&list1,5);
tail1 = Find(list1,5);
tail1->next = Find(list1,3);
PushBack(&list2,6);
PushBack(&list2,7);
PushBack(&list2,8);
tail2 = Find(list2,8);
tail2->next = Find(list1,5);
ret = CircleGetCrossNode(list1,list2);
printf("%d ",ret->data);
}
int main()
{
ListTest12();
return 0;
}