java 判断单链表是否有环

两个指针h1,h2都从头开始遍历单链表,h1每次向前走1步,h2每次向前走2步,如果h2碰到了NULL,说明环不存在;如果h2碰到本应在身后的h1说明环存在(也就是发生了套圈)。
如果环不存在,一定是h2先碰到NULL:

如果环存在,h2与h1一定会相遇,而且相遇的点在环内:h2比h1遍历的速度快,一定不会在开始的那段非环的链表部分相遇,所以当h1,h2都进入环后,h2每次移动都会使h2与h1之间在前进方向上的差距缩小1,最后,会使得h1和h2差距减少为0,也即相遇。

[code]
public class LinkedListNode {

private static boolean isLoop(NodeList p)
{
NodeEntity slow = p.head ;
NodeEntity fast = p.head ;

while(fast!=null&&fast.next!=null)
{
slow = slow.next;
fast = fast.next.next;
if(slow==fast)
{
return true ;
}
}
return false ;
}
public static void main(String[] args) {
NodeList list = new NodeList();

for(int i=0;i<3;i++)
{
list.add(i);
}

System.out.println(isLoop(list));
System.out.println(list.head.next.data);
System.out.println(list.size);
list.remove(1);
System.out.println(list.head.next.data);
System.out.println(list.head.next.next.data);
System.out.println(list.size);
}
};

class NodeEntity
{
public Object data; //存放数据
public NodeEntity next ; //存放下个节点

public NodeEntity(Object value){
this.data = value;
}
public NodeEntity()
{
this.data = null ;
this.next = null ;
}
};

class NodeList
{
public int size ;
public NodeEntity head ;

public NodeList()
{
this.size = 0;
this.head = new NodeEntity(); ;
}

public boolean contain(Object data)
{
boolean flag = false ;
NodeEntity next = head.next ;
while(next!=null)
{
if(next.data==data)
{
flag = true ;
break ;
}
next = next.next ;
}
return flag ;
}

public boolean add(Object data)
{
if(contain(data))
{
return false ;
}
else
{
NodeEntity p = new NodeEntity(data);
p.next = head.next ;
head.next = p ;
this.size++;
return true ;
}
}
public boolean remove(Object data)
{
NodeEntity current = head;
NodeEntity previous = head; //记住上一个节点
boolean flag = true ;
while (current.data != data) {
if (current.next == null) {
flag = false;
}
previous = current;
current = current.next;
}
if(current == head) {
head = head.next;
} else {
previous.next = current.next;
}
return flag;
}
};
[/code]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值