判斷乙個單鏈表是否存在環的解法如下:
問題1:快慢指標何時相遇,是否迴轉幾十圈,才相遇呢?
證明1:設環長為l,slow指標第一次進入環內,fast指標在前方的a節點處(0
0+x = (a+2x)(mod l) => 0= a+x(mod l) 兩邊同時減去x
就是說a+x對l求餘應該是0,即a+x=0,l,2l……這一系列的解取最小的那個。
得出x=l-a,就是說slow指標進入環後向前移動l-a個位,fast指標向前移動了2l-2a個位,如下圖所示:
問題2:如何求前面的子鏈長度呢?(即環入口點)
證明2:假設在fast與slow第一次相遇是,slow總共走了n步,fast走了2n步。
slow的路徑為:n=p+x,x為相遇點到環入口的距離。
fast的路徑為:2n=p+x+k*l
可以看出slow到達相遇點後再走n步,還是回到相遇點(p+x)。
將fast置到起點,步長為1,經過n步,也會到達相遇點。這個過程中只有前p步的路徑不同,所以當slow與fast再次重合是必然在環入口點上。
下面附上**:
#include using感謝兩位gocalf、xudacheng06博主的指導,參考文章:namespace
std;
struct
node
node(
const
int v,node *p=null)
};node* detectlinklistloop(node *first)
return !(fast == null || fast->next ==null);
}node* findloopport(node *head)
if (fast == null || fast->next ==null)
return
null;
slow =head;
while (slow !=fast)
return
slow;
}void
main()
判斷單鏈表是否存在環,尋找單鏈錶環的入口
判斷單鏈表是否存在環,如果存在環,找出環的入口 有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。問題 1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如何找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 fa...
判斷單鏈表是否存在環及尋找環的入口點
單鏈表反 下面給出兩種可能的實現。普通版 void reverse node head head next null head pprev 遞迴版 node reverse node pnode,node head node temp reserve pnode next,head 遞迴 temp ...
判斷單鏈表是否存在環
有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。問題 1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 fast,slow 初始值都指向頭,slow每次前進...