给定两个单链表,找出两个链表的公共节点。
算法思路 :
两个单链表有公共节点,即两个链表从某一节点开始,他们的next域都指向同一个节点。
因此从第一个公共节点以后,他们的所有的节点都是重合的,形状像一个Y字型。
暴力法:
在第一个链表上遍历每个节点,每次遍历一个节点,在第二个链表上遍历所有节点,直到找到相同的节点,否则返回NULL,时间复杂度为O(LEN1)*O(LEN2)
同步遍历:
若两个链表有公共节点,则最后一个节点必定相同,因此我们判断两个链表是否有公共节点时,只需分别遍历两个节点到最后一个节点,若两个尾结点是一样的,则说明他们有公共节点。在上面的思路中,顺序遍历两个链表到尾结点,并不能保证两个链表同时到达尾结点。因为两个链表的长度不一定相同。假设一个链表比另外一个链表多k个节点,则在长的链表上先遍历k个节点,然后同步遍历。于是在遍历中,第一个相同的节点就是公共节点。
该方法的时间复杂度为O(LEN1+LEN2)
int Length(LinkList l){ //返回链表的长度
int len=0;
while(p!=NULL){
len++;
p=p->next;
}
return len;
}
LinkList Search_lst_common(LinkList a,LinkList b){
int len1=Length(a),len2=Length(b);
LinkList longList,shortList;
if(len1>len2){
longList=a;
shortList=b;
dist=len1-len2;
}
else{
longList=b;
shortList=a;
dist=len2-len1;
}
while(dist>0){ //先将长链表遍历k个节点
dist--;
longList=LongList->next;
}
while(LongList!=NULL){
if(LongList==shortList){
return LongList;
}
else{
LongList=LongList->next;
shortList=shortList->next;
}
}
return NULL;
}