判断链表中是否有环

题目:

判断给定的链表中是否有环。如果有环则返回true,否则返回false。

输入分为两部分,第一部分为链表,第二部分代表是否有环,然后将组成的head头结点传入到函数里面。-1代表无环,其它的数字代表有环,这些参数解释仅仅是为了方便读者自测调试。实际在编程时读入的是链表的头节点。

示例:

输入:{3,2,0,-4},1

返回值:true

说明:第一部分{3,2,0,-4}代表一个链表,第二部分的1表示,-4到位置1(注:头结点为位置0),即-4->2存在一个链接,组成传入的head为一个带环的链表,返回true

输入:{1},-1

返回值:false

说明:第一部分{1}代表一个链表,-1代表无环,组成传入head为一个无环的单链表,返回false

解题思路:

利用快慢指针遍历链表,快指针每次移动2步,慢指针每次移动1步,若链表带环,则两指针一定会在环中相遇。

1.如果链表为空,或者链表只有一个结点,一定不会带环,返回NULL;

2.创建快慢指针,其初始化均指向头结点。判断两个指针的第一次移动是否存在;

3.在循环语句中,若存在快指针与慢指针相等,则指向相同的地址,此时说明存在环。否则遍历完链表后结束。

之所以快指针每次移动2步(fast = fast->next->next;),慢指针每次移动1步(slow = slow->next;),当fast == slow时存在环是因为:能被2整除的数,一定会被1整除。所以存在环的时候两个指针总能相遇。

代码示例:

```#include <stdbool.h>
/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
/**
 * 
 * @param head ListNode类 
 * @return bool布尔型
 */
bool hasCycle(struct ListNode* head ) {
    // write code here
    if(head == NULL || head->next == NULL){
        return false;
    }
    struct ListNode *slow = head;
    struct ListNode *fast = head;
    while(fast != NULL && fast->next != NULL){
        fast = fast->next->next;
        slow = slow->next;
        if(fast == slow){
            return true;
        }
    }
    return false;
    
}