判斷單鏈表是否存在環及尋找環的入口點

2021-07-03 13:53:46 字數 1893 閱讀 1948



單鏈表反**下面給出兩種可能的實現。

普通版:

void reverse(node*& head)

head->next = null;

head = pprev;

}

遞迴版:

node* reverse( node* pnode, node*& head)

node* temp = reserve(pnode->next, head);// 遞迴

temp->next = pnode;// 將下一節點置為當前節點,既前置節點

return pnode;// 返回當前節點

}

使用反轉鍊錶的方法, 每過乙個節點就把該節點的指標反向。若存在

環,反轉next指標最終會走到鍊錶頭部。若沒有環,反轉next指標會破壞鍊錶結構(使鍊錶反向), 所以為還原鍊錶,需要把鍊錶再反向一次。 這種方法的空間複雜度是o(1), 實事上我們使用了3個額外指標;而時間複雜度是o(n), 我們最多2次遍歷整個鍊錶(當鍊表中沒有環的時候)。下面給出乙個實現,但最大的問題是:若存在環,則無法還原到鍊錶的原狀態。

bool reverse(node *head) 

node *temp = curr;

curr = next;

next = next->next;

curr->next = temp;

}/* at the end of list, so there is no loop, let's reverse the list back */

next = curr->next;

curr ->next = null;

while(next!=null)

return false;

}

3. 快慢指標。 時間o(n),空間o(1),使用兩個指標。(ref:

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

bool i***itsloop(slist * head)

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

}

尋找環的入口點: 當fast按照每次2步,slow每次一步的方式走,發現fast和slow重合,確定了單向鍊錶有環路。接下來,讓fast回到鍊錶的頭部,重新走,每次步長1,那麼當fast和slow再次相遇的時候,就是環路的入口了。

證明:在fast和slow第一次相遇的時候,假定slow走了n步,環路的入口是在p步,那麼

slow走的路徑: p+c = n; c為fast和slow相交點 距離環路入口的距離

fast走的路徑: p+c+k*l = 2*n; l為環路的周長,k是整數

顯然,如果從p+c點開始,slow再走n步的話,還可以回到p+c這個點。

同時,fast從頭開始走,步長為1,經過n步,也會達到p+c這點。

顯然,在這個過程中fast和slow只有前p步驟走的路徑不同。所以當p1和p2再次重合的時候,必然是在鍊錶的環路入口點上。

slist * findloopport(slist * head)

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

return null;

slow = head;

while (slow != fast)

return slow;

}

判斷單鏈表是否存在環,尋找單鏈錶環的入口

判斷單鏈表是否存在環,如果存在環,找出環的入口 有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。問題 1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如何找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 fa...

判斷單鏈表是否存在環及尋找環的入口點

判斷乙個單鏈表是否存在環的解法如下 問題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 這一系...

判斷單鏈表是否存在環

有乙個單鏈表,其中可能有乙個環,也就是某個節點的next指向的是鍊錶中在它之前的節點,這樣在鍊錶的尾部形成一環。問題 1 如何判斷乙個鍊錶是不是這類鍊錶?2 如果鍊錶為存在環,如果找到環的入口點?解答 一 判斷鍊錶是否存在環,辦法為 設定兩個指標 fast,slow 初始值都指向頭,slow每次前進...