判斷乙個單鏈表是否有環及環的鏈結點

2021-06-27 02:30:12 字數 1521 閱讀 7718

給定乙個單鏈表,只給出頭指標h:

1、如何判斷是否存在環?

2、如何知道環的長度?

3、如何找出環的連線點在**?

4、帶環鍊錶的長度是多少?

解法:1、對於問題1,使用追趕的方法,設定兩個指標slow、fast,從頭指標開始,每次分別前進1步、2步。如存在環,則兩者相遇;如不存在環,fast遇到null退出。

2、對於問題2,記錄下問題1的碰撞點p,slow、fast從該點開始,再次碰撞所走過的運算元就是環的長度s。

3、問題3:有定理:碰撞點p到連線點的距離=頭指標到連線點的距離,因此,分別從碰撞點、頭指標開始走,相遇的那個點就是連線點。(證明在後面附註)

4、問題3中已經求出連線點距離頭指標的長度,加上問題2中求出的環的長度,二者之和就是帶環單鏈表的長度

為什麼呢?需要乙個簡單的計算過程:

(1)當fast與slow相遇時,show肯定沒有走完鍊錶,而fast已經在還裡走了n(n>= 1)圈。假設slow走了s步,那麼fast走了2s步。fast的步數還等於s走的加上環裡轉的n圈,所以有:

2s = s + nr。因此,s = nr。

(2)設整個鍊錶長為l,入口據相遇點x,起點到入口的距離為a。因為slow指標並沒有走完一圈,所以:

a + x = s,帶入第一步的結果,有:a + x = nr = (n-1)r + r = (n-1)r + l - a;即:

a = (n-1)r + l -a -x;

這說明:從頭結點到入口的距離,等於轉了(n-1)圈以後,相遇點到入口的距離。因此,我們可以在煉表頭、相遇點各設乙個指標,每次各走一步,兩個指標必定相遇,且相遇第一點為環入口點。

也許大家有乙個問題,就是為什麼「當fast與slow相遇時,show肯定沒有走完鍊錶」。這個問題比較坑,我也沒有找到很好的證明。不過大家自己畫幾個試試,會發現的確是這樣。

4.如何判斷兩個鍊錶(不帶環)是否相交?將其中的乙個鍊錶首尾相連,然後判斷另乙個鍊錶是否帶環即可。這個比較簡單,程式就省略了。

#include

typedef struct node

node,*pnode;

//判斷是否有環

bool isloop(pnode phead)

}if(fast == null || fast->next == null  )

return false;

else

return true;

}//計算環的長度

int looplength(pnode phead)

//計數

if(begin == true)

++length;

}return length;

}//求出環的入口點

node* findloopentrance(pnode phead)

}if(fast == null || fast->next == null)

return null;

slow = phead;

while(slow != fast)

return slow;}

判斷乙個單鏈表是否有環及環

判斷乙個單鏈表是否有環及環的鏈結點 蒙恩的罪人 給定乙個單鏈表,只給出頭指標h 1 如何判斷是否存在環?2 如何知道環的長度?3 如何找出環的連線點在 4 帶環鍊錶的長度是多少?解法 1 對於問題1,使用追趕的方法,設定兩個指標slow fast,從頭指標開始,每次分別前進1步 2步。如存在環,則兩...

判斷乙個單鏈表是否有環及環入口

要求 不允許修改鍊錶結構 時間複雜度o n 空間複雜度o 1 判斷是否有環 如果鍊錶有環,那麼在遍歷時則會陷入死迴圈。使用快慢指標 快指標移動2步,慢指標移動1步 如果走到某一步,快慢指標相遇,則說明有環 環入口點 我們假設鍊錶頭部到環入口距離 len,環入口到快慢指標交匯點的距離為x,環的長度為r...

判斷乙個單鏈表是否有環

一 判斷鍊錶是否存在環 設定兩個指標 fast,slow 初始值都指向頭,slow每次前進一步,fast每次前進二步,如果鍊錶存在環,則fast必定先進入 環,而slow後進入環,兩個指標必定相遇。當然,fast先行頭到尾部為null,則為無環鏈表 程式如下 bool i itsloop listn...