定義:
迴圈鏈表:鏈表中一個節點的next指標指向先前已經存在的節點,導致鏈表中出現環。
問題1:判斷是否有環
#include <cstring>#include <iostream>using namespace std;struct node{char value;node* next;node(char rhs){value = rhs; next = NULL;}};bool isLoop(node* head){ if (head == NULL){ return false;}node* slow = head;node* fast = head;while((fast!= NULL) && (fast->next != NULL)){ slow = slow->next;fast = fast->next->next;if (slow == fast){break;}}return !(fast == NULL || fast->next == NULL);}int main() { node A('A');node B('B');node C('C');node D('D');node E('E');node F('F');node G('G');node H('H');node I('I');node J('J');node K('K');A.next = &B;B.next = &C;C.next = &D;D.next = &E;E.next = &F;F.next = &G;G.next = &H;H.next = &I;I.next = &J;J.next = &K;K.next = &D;if (isLoop(&A)){ cout<<"Loop";}else{cout<<"No loop";}return 0;}
問題2:找到這個環的起始點
輸入: A->B->C->D->E->F->G->H->I->J->K->D
輸出:D
分析:
當fast與slow相遇時, slow肯定沒有遍曆完鏈表,而fast在環內肯定迴圈了1圈以上。
設環的長度為r, 相遇時fast在環內走了n個整圈(n > 1),slow走了s步,fast走了2s步,則:
2s = s + nr -> s = nr
設整個鏈表的長度為L,環進入點與相遇點的距離為x,鏈表起點到環進入點的距離為a,則:
a + x = s = nr (slow走過的步數,slow為走過一圈)
a + x = (n-1)r + r = (n-1)r + (L - a) -> a = (n-1)r + (r - x)
(r - x) 為相遇點到環進入點的距離; 因此,鏈表頭到環進入點的距離 等於 (n-1)個環迴圈 + 相遇點到環入口的距離。
我們從鏈表頭和相遇點分別設定一個指標,每次各走一步,則兩個指標必定相遇,且第一個相遇點為環進入點。
#include <cstring>#include <iostream>using namespace std;struct node{char value;node* next;node(char rhs){value = rhs;next = NULL;}};node* isLoop(node* head){if (head == NULL){return false;}node* slow = head;node* fast = head;while((fast!= NULL) && (fast->next != NULL)){slow = slow->next;fast = fast->next->next;if (slow == fast){break;}} if (fast == NULL || fast->next == NULL) { return NULL; } // currently, the list is looped slow = head; while(slow != fast) { slow = slow->next; fast = fast->next; } return slow;}int main() {node A('A');node B('B');node C('C');node D('D');node E('E');node F('F');node G('G');node H('H');node I('I');node J('J');node K('K');A.next = &B;B.next = &C;C.next = &D;D.next = &E;E.next = &F;F.next = &G;G.next = &H;H.next = &I;I.next = &J;J.next = &K;K.next = &D;node* p;if ((p= isLoop(&A))!= NULL){cout<<"Loop, the interaction node is "<<p->value;}else{cout<<"No loop";}return 0;}