有環連結串列的環起點
阿新 • • 發佈:2018-12-30
用兩個指標,一個快指標一次走兩步,一個慢指標一次走一步。快慢指標可以重合表示連結串列有環,此時距離環起點的距離和起點距離環起點的距離相等。
#include "bits/stdc++.h" using namespace std; struct List { List* next; }; List* beginOfCircle(List* p1, List* p2) { while (p1 != p2) { p1 = p1->next; p2 = p2->next; } return p1; } List* hasCircle(List* head) { List* fast = head; List* slow = head; while (slow != NULL && fast != NULL && fast->next != NULL) { slow = slow->next; fast = fast->next->next; if (slow == fast) { return beginOfCircle(head, slow); } } return NULL; } List* init() { List* rec = (List*)malloc(sizeof(List)); rec->next = NULL; } int main() { List* head; List* ans; List* now; List* res; /* head = (List*)malloc(sizeof(List)); head->next = (List*)malloc(sizeof(List)); head->next->next = (List*)malloc(sizeof(List));; head->next->next->next = (List*)malloc(sizeof(List)); head->next->next->next = head->next; res = hasCircle(head); if (res == head->next) { puts("YES"); } else { puts("NO"); }*/ int n, m; scanf("%d %d", &n, &m); head = init(); now = head; while (--n) { now->next = init(); now = now->next; } ans = now; if (m == 0) { res = hasCircle(head); if (res == ans) { puts("YES"); } else { puts("NO"); } return 0; } while (--m) { now->next = init(); now = now->next; } now->next = ans; res = hasCircle(head); if (res == ans) { puts("YES"); } else { puts("NO"); } return 0; }
main函式裡為驗證,可以輸入環起點的編號n和一個環的長度m。最後返回的結果等於環起點輸出“YES”,當連結串列中無環的情況下返回NULL輸出結果為“NO”;