链表的正确相交情况如下:
判断两个链表是否相交
//确定两个单链表是否相交 (用两个指针跑到两个单链表的尾结点,然后判断是否是同一个尾结点)
bool Intersect(PNode plist1, PNode plist2)
{
//assert
PNode p1 = plist1;
PNode p2 = plist2;
for(p1; p1->next!=NULL; p1=p1->next); //此时for循环结束 p1在plist1这个单链表的尾结点上
for(p2; p2->next!=NULL; p2=p2->next); //此时for循环结束 p2在plist2这个单链表的尾结点上
return p1 == p2;
}
判断两个链表是否相交并求出相交点
//确定两个单链表是否相交,并且相交的话,返回第一个相交点
struct Node *Intersect_get_Node(PNode plist1, PNode plist2)
{
//assert
int len1 = Get_length(plist1);
int len2 = Get_length(plist2);
//接下来 我们需要保证 让p永远指向较长的单链表
PNode p = len1>=len2 ? plist1 : plist2;
PNode q = len1>=len2 ? plist2 : plist1;
for(int i=0; i<abs(len1-len2); i++)//abs 计算绝对值
{
p = p->next;
}
//此时,p已经将差值跑完 这个时候 只需要循环判断p和q是否是用一个节点即可
while(p != q)//这里要么p和q指向有效地址 退出循环 要么p==q==NULL 退出循环
{
p = p->next;
q = q->next;
}
return p; //return q;
}
测试:
int main()
{
Node head1;
Init_list(&head1);
for (int i = 0; i < 10; i++)
{
Insert_pos(&head1, i, i + 1);
}
Node head2;
Init_list(&head2);
for (int i = 0; i < 20; i++)
{
Insert_pos(&head2, i, i + 101);
}
Show(&head1);
Show(&head2);
bool tag1 = Intersect(&head1, &head2);
if (tag1)
{
printf("相交了\n");
}
else
{
printf("没有相交\n");
}
PNode p = &head2;
for (int i = 0; i < 12; i++)
{
p = p->next;//p最后指向plist2的 112
}
PNode q = &head1;
for (int i = 0; i < 5; i++)
{
q = q->next;//q最后指向plist1的 5
}
p->next = q->next;//手动发生相交
Show(&head1);
Show(&head2);
//1 2 3 4 5 6 7 8 9 10
//101 102 103 104 105 106 107 108 109 110 111 112 6 7 8 9 10
tag1 = Intersect(&head1, &head2);
if (tag1)
{
printf("相交了\n");
}
else
{
printf("没有相交\n");
}
struct Node* tmp = Intersect_get_Node(&head1, &head2);
if (tmp != NULL)
{
printf("相交点的有效值为:%d\n", tmp->data);
}
bool tag2 = Del_Node((&head1)->next);
if (tag2)
{
Show(&head1);
}
return 0;
}