环形链表原理:前文介绍了快慢指针的应用,同时我们也可以通过快慢指针来判断当前链表是否有环(快慢指针是否相遇)。假如把链表比作一条跑道,链表中有环,那么这条跑道就是一条环形跑道,两个速度不一样的人在上面奔跑,那么这两个人迟早会相遇。
- 第一步:定义两个快慢指针
- 第二步:快指针的步长是2,慢指针的步长是1
- 第三步:用这两个指针去遍历链表
- 第四步:判断快慢指针在遍历过程中有没有相遇,若相遇,则说明是环形链表,未相遇,则说明是普通的单向链表
- 注意的点:判断两指针是否相遇时,不应该使用fast.item.equals(slow.item),因为链表中不同的结点可能存储的数据是一样的
而应用使用引用类型的Node类对象去判断两指针指向的地址是否完全相同
//判断是否是环形链表
public static boolean isCycle(Node first){
//定义两个快慢指针
Node fast=first;
Node slow=first;
//遍历链表,如果两指针相遇,则存在环
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
//相遇
if(fast.equals(slow)){
return true;
}
}
return false;
}
测试代码:
package com.company.test;
/**
* @ProjectName 数据结构实操
* @ClassName FastSlowTest
* @Description // 快慢指针,解决中间值问题
* @Email 2992794262@qq.com
* @Author ASUS
* @Date 2022/1/7
**/
public class isCycleLinkCheckTest {
public static void main(String[] args) {
Node first=new Node("aa",null);
Node second=new Node("bb",null);
Node third=new Node("cc",null);
Node fourth=new Node("dd",null);
Node fifth=new Node("ee",null);
Node sixth=new Node("ff",null);
Node seventh=new Node("gg",null);
first.next=second;
second.next=third;
third.next=fourth;
fourth.next=fifth;
fifth.next=sixth;
sixth.next=seventh;
//环形链表
seventh.next=first;
boolean cycle = isCycle(first);
System.out.println("是否存在环:"+cycle);
}
//判断是否是环形链表
public static boolean isCycle(Node first){
//定义两个快慢指针
Node fast=first;
Node slow=first;
//遍历链表,如果两指针相遇,则存在环
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
//相遇
if(fast.equals(slow)){
return true;
}
}
return false;
}
private static class Node<T>{
T item;
Node next;
public Node(T item, Node next) {
this.item = item;
this.next = next;
}
}
}