两个指针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]
如果环不存在,一定是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]