今天mayuyu來帶領你們討論如下三個問題:
(1)如何判斷乙個單鏈表是否存在環 ?
(2)如果存在環,如何找到環的入口點?
(3)兩個鍊錶中有環時,如何判斷相交?
問題一
我們設定兩個指標,分別是fast和slow,初始都指向這個單向鍊錶的表頭,fast每次走兩步,而slow每次走一步,
所以,我們知道如果有環,那麼fast先進入環,slow後進入環,在經過若干次這樣的步驟,必定會有fast與slow
相遇,那麼我們就能判斷是否存在環了。如果不存在環,則fast先走到鍊錶尾。
所以我們很容易得到如下**:
bool isloop(list *head)
return false;
}
問題二上面問題一我們已經能判斷乙個單向的鍊錶是否存在環,如果乙個單向鍊錶存在環,我們如何求它的環入口點?
如下圖
首先,我們設head到入口點的距離為
鍊錶總長度為
slow多走了
所以我們很容易得到
又由於
這個表示式說明從相遇點到入口點的距離與head到入口點的距離取餘後是相等的。所以我們可以在相遇點和head處
各設定乙個指標,然後同時走,它們會在入口處相遇,這樣我們也就能找到這個入口了。
**如下:
list *findport(list *head)
if(fast == null || fast-next == null)
return null;
slow = head;
while(slow != fast)
return slow;
}
問題三實際上,我們先要明確乙個事實,那就是如果乙個單鏈表有環,另乙個單鏈表沒有環,那麼這兩個單鏈表一定不會
相交。這是單鏈表的next指向的唯一性決定的,乙個節點不可能有兩個或者多個後繼分支。
所以,如果是兩個有環鏈表相交,那麼它們一定存在乙個公共的環,大致如下兩個圖形:
所以,明確了以上事實之後,我們可以這樣來做:
先分別求出這兩個有環鏈表的環的入口點,如果入口點相等,那麼說明這兩個有環鏈表就相交了。如果不相等,就有
兩種情況:
(1)兩個有環鏈表不相交
(2)它們相交但環入口點不同
那麼我們如何判斷,這個就比較簡單了。
我們設乙個環的入口點為port,在另乙個環的入口點設定乙個指標p往後走,如果一周內出現p->next == port,
那麼說明這兩個有環鏈表共環,也就是說相交,否則這兩個有環鏈表不相交。
判斷單向鍊錶中是否存在環
程式設計思路 追趕問題 在同一圓環上,當兩個物體以不同的速度前進時,他們總能在某個時間點上再次相遇 即當兩個指標以不同的移動速度在乙個單向鍊錶上移動時,若該鍊錶有環的存在,則這兩個指標總會在某一時刻同時指向鍊錶上的同乙個節點 include struct hasring bool ishasring...
判斷單鏈表是否存在環,判斷兩個鍊錶是否相交問題詳解
摘要 有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?擴充套件 判斷兩個單鏈表是否相交,如果相交,給出相交的第乙個點。有乙個單鏈表,其中可能有乙個環,也就是某...
判斷單鏈表是否存在環,判斷兩個鍊錶是否相交問題詳解
有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。問題 1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 fast,slow 初始值都指向頭,slow每次前進...