算法和数据结构是面试考核的重点,其中经常问到单链表的问题,比如单链表的逆置、判断单链表是否有环等问题,这些主要考察的程序员的基本代码能力,今天给大家一起学习一下如何判断单链表是否有环。
那么如何判断一个单链表是否有环呢?(这个好像是谷歌的面试题目)先说一下算法思想:
我们可以设置两个指针分别叫做slow和fast,遍历这个链表,其中让slow指针每次走一步,而fast指针则每次走两步。大家想一下,如果链表有环会出现什么情况,链表有环肯定在某一个时刻这两个指针会指向同一个节点,也就是说如果出现slow.data == fast.data表示链表有环(前提是这个链表的各个节点的数据域都不相同);那么什么情况下是没有环的呢?链表如果没有环那么fast指针会先到达链表的末尾,此时链表肯定是不存在环的。算法的思路很简单,下面给出具体的代码实现:
package cn.cqupt.linked;
public class CheckLinkLoop {
private static class Node{
private int data;
private Node next;
Node(){}
Node(int data){
this.data = data;
this.next = null;
}
Node(int data,Node next){
this.data = data;
this.next = next;
}
}
public static boolean isLoop(Node head){
Node slow = head.next;
Node fast = head.next.next;
// 链表为空或者只有一个节点
if(slow == null || fast == null){
return false;
}
while(slow.next != null){
// 只有 两个节点,当然是不存在循环的
if(fast.next == null){
return false;
}
// 如果slow的数据域和fast的数据域相同,则表示有环
if(slow.data == fast.data){
return true;
}
// slow指针走一步,fast走两步
slow = slow.next;
fast = fast.next.next;
//如果fast走到最后为空,表示没有环
if(fast == null){
return false;
}
}
return false;
}
public static void main(String[] args){
// 构造链表 1->2->3->4->5->6-4;
Node head = new Node();
Node a = new Node(1);
Node b = new Node(2);
Node c = new Node(3);
Node d = new Node(4);
Node e = new Node(5);
Node f = new Node(6);
head.next = a;
a.next = b;
b.next = c;
c.next = d;
d.next = e;
e.next = f;
f.next = d;
// 结果
System.out.println(isLoop(head));
}
}