有环链表的环起点

用两个指针,一个快指针一次走两步,一个慢指针一次走一步。快慢指针可以重合表示链表有环,此时距离环起点的距离和起点距离环起点的距离相等。

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

猜你喜欢

转载自www.cnblogs.com/Angel-Demon/p/10199477.html