7、判断链表是否有环

一、解决思路:

  对于这个问题我们可以采用“快慢指针”的方法。就是有两个指针fast和slow,开始的时候两个指针都指向链表头head,然后在每一步操作中slow向前走一步即:slow = slow->next,而fast每一步向前两步即:fast = fast->next->next。由于fast要比slow移动的快,如果有环,fast一定会先进入环,而slow后进入环。当两个指针都进入环之后,经过一定步的操作之后二者一定能够在环上相遇,并且此时slow还没有绕环一圈,也就是说一定是在slow走完第一圈之前相遇。证明可以看下图:

      

一、代码:

#include "stdafx.h"
#include<windows.h>
#include<iostream>

#define LIST_LEN    10
using namespace std;

struct list_node
{
    int value;
    list_node *next;
};

list_node *init_list(int len)
{
    list_node *head, *p, *q;

    p = (list_node *)malloc(sizeof(list_node));
    p->value = 0;
    head = p;

    for (int i = 1; i < len; i++)
    {
        q = (list_node *)malloc(sizeof(list_node));
        q->value = 2 * i;
        p->next = q;
        p = q;
    }
    p->next = NULL;

    return head;
}

int show_list(list_node *head)
{
    if (head == NULL) return 0;

    list_node *p = head;

    while (p)
    {
        printf("%4d", p->value);
        p = p->next;
    }
    printf("
");

    return 0;
}

bool ExitLoop(list_node *head)
{
    list_node *fast, *slow;
    slow = fast = head;

    while (slow != NULL && fast->next != NULL &&fast->next->next!=NULL)
    {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast)
            return true;
    }
    return false;
}

int main()
{
    list_node *head = init_list(LIST_LEN);
    show_list(head);

    bool bIsLoop = ExitLoop(head);
    
    printf("%d
", bIsLoop);

    system("pause");
    return 0;
}
原文地址:https://www.cnblogs.com/zwj-199306231519/p/14282309.html