如何判斷乙個鍊錶是否有環,如果有環,並找出環的入口

2021-07-23 03:14:06 字數 1836 閱讀 9848

首先如何判斷乙個鍊錶是否有環:

設定兩個指標

(fast, slow)

,初始值都指向頭,

slow

每次前進一步,

fast

每次前進二步,如果鍊錶存在環,則

fast

必定先進入環,而

slow

後進入環,兩個指標必定相遇。

(當然,

fast

先行頭到尾部為

null

,則為無環鏈表

)程式如下:

bool i***itsloop(slist *head)

return !(fast == null || fast->next == null);

}

下面看如何找這個環的入口:

第一種方法:

當fast

若與slow相遇時

slow

肯定沒有走遍歷完鍊錶

(這是因為如果這個鍊錶整個是個環的話,當

slow

恰好到達鍊錶終點的時候

fast

正好追上

slow

,當這個環不是整個鍊錶的時候,則肯定在

slow

到達終點的時候就被

fast

追上了)

,而fast

已經在環內迴圈了n圈

(1<=n)。

假設slow走了s

步,則fast

走了2s

步(fast

步數還等於

s加上在環上多轉的

n圈),

設環長為

r,則:

因為2s = s + nr

所以得出

s= nr

設整個鍊錶長

l,環入口

與相遇點距離為

x,起點到環入口點的距離為a。

則有a + x = 

s 推出

a = nr-x

分解有a + x = (n – 1)r +r = (n-1)r + l - aa = (n-1)r + (l – a – x)(l – a – x)

相遇點到環入口點的距離,

由此可知,從煉表頭到環入口點等於(n-1)

迴圈內環

+相遇點到環入口點

於是我們從煉表頭、與相遇點分別設乙個指標,每次各走一步,兩個指標必定相遇,且相遇第一點為環入口點。程式描述如下:

slist* findloopport(slist *head)

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

return null;

slow = head;

while (slow != fast)

return slow;

}

兩個**合二為一為

lnode* getloopnode(lnode* head)

//定義乙個快指標和乙個慢指標

lnode* fast = head;

lnode* slow = head;

while (fast && (fast->next))

}return slow;}}

return null;

}

判斷鍊錶是否有環,如果有,找到環的入口位置

判斷乙個鍊錶是否有環,空間複雜度是o 1 如果不考慮空間複雜度,可以使用乙個map記錄走過的節點,當遇到第乙個在map中存在的節點時,就說明回到了出發點,即鍊錶有環,同時也找到了環的入口。不適用額外記憶體空間的技巧是使用快慢指標,即採用兩個指標walker和runner,walker每次移動一步而r...

判斷乙個單鏈表是否有環,如果有,找出環的起始位置

第一種方法是從單鏈表head開始,每遍歷乙個,就把那個node放在hashset裡,走到下乙個的時候,把該node放在hashset裡查詢,如果有相同的,就表示有環,如果走到單鏈表最後乙個node,在hashset裡都沒有重複的node,就表示沒有環。這種方法需要o n 的空間和時間。第二種方法是設...

判斷乙個鍊錶是否有環

1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 fast,slow 初始值都指向頭,slow每次前進一步,fast每次前進二步,如果鍊錶存在環,則fast必定先進入環,而slow後進入環,兩個指標必定相遇。當然,fas...