43.png

    1. /*
    2. 设计一个算法判断一个链表是否有环
    3. 分析:我们可以想象一下,在一个有环的赛道上,有两个人跑步,一个人跑得快,一个人跑得慢,试想,时间充足的情况下,跑得快
    4. 的那个人是不是会再次遇到跑的慢的人呢?所以对于这道题,我们也可以通过快慢指针来处理,p指针一次移动两个节点,q指针一次移动
    5. 一个节点,如果他们再次相遇了,说明链表有环,如果p指针为NULL了,说明无环。同时我们需要记录p、q各走的步数,用以确定
    6. 环的入口点
    7. */
    8. struct Link {
    9. union {
    10. int data;
    11. }type;
    12. struct Link *next;
    13. };
    14. #include <stdio.h>
    15. Link *isLoop(Link *h) {
    16. struct Link *fast = h, *slow = h;
    17. while (slow&&fast&&fast->next) {
    18. slow = slow->next;
    19. fast = fast->next->next;
    20. if (slow == fast) {//再次相遇,说明有环
    21. break;
    22. }
    23. }
    24. if (slow==NULL||fast==NULL||fast->next==NULL) {
    25. return NULL;
    26. }
    27. fast = h;
    28. while (fast != slow) {
    29. fast = fast->next;
    30. slow = slow->next;
    31. }
    32. return fast;
    33. }
    34. int main() {
    35. struct Link *head,*l,*s;
    36. int count = 0;
    37. Link *createLink(int);
    38. head = createLink(0);
    39. l = head;
    40. while (l->next) {
    41. l = l->next;
    42. }
    43. l->next = head->next->next->next;//手动设置一个环
    44. s=isLoop(head);
    45. if (s) {
    46. printf("链表环起始节点值为:%d",s->type.data);
    47. }
    48. else {
    49. printf("该链表无环");
    50. }
    51. return 0;
    52. }