判断链表中是否有环
题目:
判断给定的链表中是否有环。如果有环则返回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;
}