概念部分转载于http://blog.csdn.net/zwhlxl/article/details/45745825
问题描述
判断两个单链表是否相交,如果相交,给出相交的第一个点
一.两个链表都不存在环相交的
链表示意图如下所示。
解题思路
方法一
两个没有环的链表如果是相交于某一结点,如上图所示,这个结点后面都是共有的。所以如果两个链表相交,那么两个链表的尾结点的地址也是一样的。程序实现时分别遍历两个单链表,直到尾结点。判断尾结点地址是否相等即可。时间复杂度为O(L1+L2)。
如何找到第一个相交结点?判断是否相交的时候,记录下两个链表的长度,算出长度差len,接着先让较长的链表遍历len个长度,然后两个链表同时遍历,判断是否相等,如果相等,就是第一个相交的结点。
方法二
另外一个方法将一个链表首尾相接,然后判断另外一个链表是否有环,如果有环,则两个链表相交。那么求第一个交点则求出有环的的那个链表的环结点即是。
第一种方法代码如下:
1 node * findPoint(node*head1,node*head2) 2 { 3 if(head1==NULL||head2==NULL) printf("没有交点 "); 4 node*p1=head1; 5 node*p2=head2; 6 node *p=NULL; 7 int n,m,len; 8 int i=0; 9 int j=0; 10 while(p1->next) 11 { 12 p1=p1->next; 13 i++; 14 } 15 while(p2->next) 16 { 17 p2=p2->next; 18 j++; 19 } 20 if(p1!=p2) printf("没有交点 ");//如果有交点,至少最后一个点是相同的 21 else 22 { 23 p1=head1;//一定要重新赋值或者找另外的变量在上面接一下初始值 24 p2=head2; 25 int k=0; 26 if(i>j) 27 { 28 len=i-j; 29 while(k<len) 30 { 31 p1=p1->next; 32 k++; 33 } 34 } 35 else 36 { 37 len=j-i; 38 while(k<len) 39 { 40 p2=p2->next; 41 k++; 42 } 43 } 44 //一起走,边走边判断是否有交点 45 while(p1!=p2) 46 { 47 p1=p1->next; 48 p2=p2->next; 49 } 50 } 51 return p1; 52 }
二.如果两个链表是有环链表呢?
当两个链表中有环时,相交的判断:
(1)首先分别找出两个链表入环的第一个结点记为p1,p2
(2)如果p1==p2,说明两个链表在入环之前或入环的第一个结点相交;则此时可以转为两个链表均不带环相交的判断,把p1,p2当作最后的末尾结点
(3)如果p1!=p2,此时两个链表可能完全不相交;也可能两个链表完全共有同一个环。
此时,判断p1->next与p2->next是否相等,如果相等则两链表完全共环;如果不相等,则完全不相交。
当一个链表中有环,一个链表中没有环时,两个链表必不相交。