1. 程式人生 > >有環連結串列的環起點

有環連結串列的環起點

用兩個指標,一個快指標一次走兩步,一個慢指標一次走一步。快慢指標可以重合表示連結串列有環,此時距離環起點的距離和起點距離環起點的距離相等。

#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”;