求兩個鏈表的交點

判斷兩個單鏈表是否相交共有三種狀況:算法

1,兩個單鏈表都沒有環。ide

2,兩個單鏈表中 一個有環,一個沒有環。oop

3,兩個鏈表都有環。this

看第一種狀況,連個單鏈表相交,只能是y型相交,不多是x型相交,理由以下,有兩個鏈表,La,Lb,他們的交點設爲p吧,假設在La中,p的前驅爲pre_a,後繼爲next_a,在Lb中,前驅爲pre_b,後繼爲next_b,則pre_a->next=p,pre_b_next=p,接下來看後繼,p->next=next_a,p->next=next_b;而後問題就出來了,你們應該知道,一個單鏈表的next指針只有一個,怎麼跑出兩個來呢,因此兩個鏈表相交只能值Y型相交。繼續解釋,兩個鏈表從交點後的其餘節點都是同樣的,這樣只判斷最後一個節點是否相交就能夠知道兩個單鏈表時候是相交了。判斷完以後,還須要尋找鏈表的交點。求出兩個鏈表的長度:len_a,len_b,求出差值len(len爲較大的減去較小的值)。讓長的那個先走len步,以後兩個鏈表一塊兒走,直至有點相同的時候。下面給出獨立的算法:spa

typedef struct LNode
{
int data;
struct LNode *next;
}LNode,*LinkList;
void is_intersect(LinkList La,LinkList Lb)
{
LNode *pa,*pb;
int len_a=0,len_b=0;
pa=La;
pb=Lb;
while(pa->next)
{
len_a++;
pa=pa->next;
}
len_a+=1;
while(pb->next)
{
len_b++;
pb=pb->next;
}
len_b+=1;
int temp,i=0;
pa=La;
pb=Lb;
if(len_a>len_b)
{
temp=len_a-len_b;
while(i<len_a)
{
pa=pa->next;
i++;
}
}
else
{
temp=len_b-len_a;
while(i<len_b)
{
pb=pb->next;
i++;
}
}
while(pa!=pb)
{
pa=pa->next;
pb=pb->next;
}
return pa;
}指針

再次,看第二種狀況,一個有環,一個無環,那麼兩個鏈表確定不相交,解釋以下:orm

1347783720_1268.png

假設鏈表La有環,Lb無環,交點在La環點以前,那麼,Lb的最後一個節點確定在環上,要否則在延伸一下Lb也有環了。仍是原來那麼觀點,就是一個節點只能有一個指向下個節點的指針,紅點處的La的元素有下一個元素,而Lb的爲NULL,則這種狀況不成立。若交點在La環點以後,也不能成立,道理同樣。it

最後就來看第三種狀況,兩個鏈表都有環,先給出有環的和求環入口點的算法:給定一個鏈表,增設兩個指針,一個fast,一個slow,fast每次走兩步,slow每次走一步,如有環,兩個節點確定會相遇,畫下圖。求環入口點(環點)的理論基礎:設鏈表長度爲len,從表頭到環入口點的距離爲x,兩個指針的交點爲y,環的長度爲r,從交點到入口點還須要走z步。有兩個指針相交得出:y+nr=2y。fast走的步數是slow的兩倍。以後x+r=len;y+z=len;整理三個實在得出:x+r=(n-1)r+z;你們可畫圖,n值通常狀況下爲2.最後x=z。這就說明,從鏈表頭結點開始(此鏈表頭結點有數據),到環的入口點,和fast,slow相交點到環入口點的距離同樣。有了理論基礎,給出算法以下:ast

LNode* is_cylic(LinkList L)
{
LNode *fast,*slow;
fast=L;
slow=L;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(fast==slow)
break;
}
if(fast==NULL||fast->next==NULL)
return NULL;//if return null means this LinkList has no loop.
slow=L;
while(slow!=fast)
{
slow=slow->next;
fast=fast->next;
}
return slow;
}class

求得環的入口點後還須要分紅三種狀況,一種比較特殊的是兩個鏈表的入口點即爲交點。兩外兩種狀況看下圖:

1347785274_4356.png

第一種狀況是交點在兩個環的入口點以前,第二種狀況是交點在第一個鏈表入口點以後。前一種比較好求,即求得兩個鏈表的入口點分別是p1,p2,if(p1==p2),說明在入口點以前,那麼遍歷兩個表,找到入口點以前的長度,而後依照無環單鏈表第一個交點的方法去找 。可是若是兩個入口點不同,那麼求他們的第一個交點又做何解釋呢。其實能夠這麼理解,相對於La(入口點爲p1),來講他和Lb的第一個交點即爲自身的入口點,而對於Lb(入口點爲p2)來講,它與La的第一個相交點爲p2。(註明:此時的第一個相交點覺得相對單鏈表的開頭來講,順序行走後的)。給出思路,解法就很簡單了。

相關文章
相關標籤/搜索