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,也即相遇。


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;
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值