如何判断单链表有环?
如题,如何判断单链表有环呢?
思路一:快慢指针,定义两个指针,同时指向链表头结点。指针移动速度不一样,一个快,一个慢,循环链表时,如果快慢指针相遇,则有环。很好理解,犹如跑道上的两个人,有人跑的快,有人跑的慢,同时起跑,跑的快的人,必然在比跑的慢的多跑一圈后,会追上跑得慢的。
思路二:遍历链表,每个元素都往set集合里装,如果有环,肯定会重复,新增元素时判断set是否包含该元素,即可判断链表是否有环:包含则有环,完成遍历,不包含则无环。
如图:
上代码:
定义链表节点
/**
* 链表节点
*
* @author zab
* @date 2022/5/19 22:54
*/
public class Node {
public Object data;
public Node next;
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
两种思路实现
/**
* 链表环状检查工具
*
* @author zab
* @date 2022/6/12 22:09
*/
public class ListCycleCheckUtil {
private ListCycleCheckUtil(){}
/**
* 通过移动快慢指针判断链表是否有环
* 为什么?快慢指针可以判断链表是否有环?
* 因为两个人在操场跑步,跑的快的,在某一时刻会与跑的慢的相遇了,证明是环形跑道
*
* @author zab
* @date 2022/6/12 23:02
* @param head 链表头结点
* @return true 有环
*/
public static boolean hasCycle(Node head){
if (head == null || head.getNext() == null) {
return false;
}
Node fast;
Node slow;
fast = head;
slow = head;
while(true){
fast = fast.getNext();
if(fast == null){
break;
}
fast = fast.getNext();
slow = slow.getNext();
if(fast == null){
break;
}
if (fast == slow){
return true;
}
}
return false;
}
/**
* 通过set判断链表是否有环,变量链表,不断往set集合加元素,如果发现有重复,就是环形
*
* @author zab
* @date 2022/6/12 23:02
* @param head 链表头结点
* @return true 有环
*/
public static boolean hasCycle1(Node head){
if (head == null || head.getNext() == null) {
return false;
}
HashSet<Node> nodes = new HashSet<>();
Node temp = head;
while(true){
temp = temp.getNext();
if(temp == null){
break;
}
if (nodes.contains(temp)) {
return true;
}
nodes.add(temp);
}
return false;
}
public static void main(String[] args) {
Node test1 = new Node();
test1.setData(1);
Node test2 = new Node();
test2.setData(2);
Node test3 = new Node();
test3.setData(3);
Node test4 = new Node();
test4.setData(4);
Node test5 = new Node();
test5.setData(5);
Node test6 = new Node();
test6.setData(6);
test1.setNext(test2);
test2.setNext(test3);
test3.setNext(test4);
test4.setNext(test5);
test5.setNext(test6);
test6.setNext(test3);
boolean b = hasCycle1(test1);
System.out.println(b);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?