问题描述:
拓展:
首先要明白什么是公共结点:两个链表有公共结点,即两个链表从某一结点开始,它们的next都指向同一个结点。由于每个单链表结点只有一个next域,因此从第一个公共结点开始,之后它们所有的结点都是重合的,不可能再出现分叉,若出现了分叉,则就与单链表每个结点只有一个next域矛盾了。所以两个有公共结点而部分重合的单链表,形状看起来像Y,而不可能像X。
算法思路:
假设两个单链表A、B的公共部分长度为c,A除去公共部分的长度为a,B除去公共部分的长度为b。
情况一:A、B有公共结点,则a+c+b = b+c+a;
情况二:A、B没有公共结点,即c = 0,a+b = b+a,此时指针p1 = p2 = NULL;
代码:
注意:
我写的代码中单链表都是有头结点的。
普通版:
LNode* FindFirstCommonNode(LinkList L1,LinkList L2){
LNode *p1 = L1 -> next,*p2 = L2 -> next;
while((p1 != p2)){
if(p1 != NULL){
p1 = p1 -> next;
}
else{
p1 = L2 -> next;
}
if(p2 != NULL){
p2 = p2 -> next;
}
else{
p2 = L1 -> next;
}
}
if(p1 == p2){
return p1;
}
else{
return NULL;
}
}
我们注意到上述代码虽然很清晰,但是不够简练,可以简化一些地方,下面是终极简化版本:
进阶版:
LNode* FindFirstCommonNode(LinkList L1,LinkList L2){
LNode *p1 = L1 -> next,*p2 = L2 -> next;
while((p1 != p2)){
p1 = (p1 == NULL)? L2 -> next:p1 -> next;
p2 = (p2 == NULL)? L1 -> next:p2 -> next;
}
return p1;
}
可能会引起迷惑的地方:
当两个链表没有公共结点的时候不是会陷入while的死循环吗?
答案是不会。
因为若两链表没有公共结点,则公共部分c=0,a+b = b+a,也就是说两个指针p1、p2一定会在各遍历完一遍两个链表时相遇,且此时p1、p2都指向NULL,则会跳出while循环。