java判断单链表是否有环

思路分析

假设,现在有一个存在环的单链表。

// null->node1->node2->node3->node4->node5->node6->node1

对其进行分析,可以设置2个“指针”。

singleStep 每次向后 更新一个节点;doubleStep 每次向后更新两个节点。

步骤如下:

java代码

public class Linked {

	// Node静态类
	private static class Node {
		private Integer data;
		private Node next;
		
		Node(){}
		Node(Integer data){
			this(data, null);
		}
		Node(Integer data, Node next){
			this.data = data;
			this.next = next;
		}
	}
	
	/**
	 * 判断单链表是否有环。
	 * @param head 头指针
	 * @return 有环返回true,否则返回false
	 */
	public static boolean isLoop(Node head) {
		// 指针,头指针的下一个为单步,下一个的下一个是双步
		Node singleStep = head.next;
		Node doubleStep = head.next.next;

		// 存在2个以上的结点时
		while(doubleStep != null) {
			Integer num1 = singleStep.data;
			Integer num2 = doubleStep.data;
			// 当值相同时,说明是存在环了
			if(num1 == num2) return true;
			
			// 更新2个节点
			singleStep = singleStep.next;
			doubleStep = doubleStep.next.next;
			// 双步的结点先更新到链表尾部,说明不存在环
			if(doubleStep == null) return false;
		}
		
		// 只存在一个节点,必然是环 
		return true;
	}
	
	public static void main(String[] args) {
		Node head = new Node();// 头为null
		// 6个节点
		Node node1 = new Node(1);
		Node node2 = new Node(2);
		Node node3 = new Node(3);
		Node node4 = new Node(4);
		Node node5 = new Node(5);
		Node node6 = new Node(6);
		
		// 创建有环链表
		// null->node1->node2->node3->node4->node5->node6->node3
		head.next = node1;
		node1.next = node2;
		node2.next = node3;
		node3.next = node4;
		node4.next = node5;
		node5.next = node6;
		node6.next = node1;
		
		boolean loop = isLoop(head);
		System.out.println(loop);

	}
}

打印结果:true

总结分析

单链表是否存在环,重要的一点需要明白,有环时是什么情况,这里的条件是当【链表中存在两个节点的值相同时,因为我的数据是Integer类型的,所以可以直接使用==来判断其值是否相同。】

当存储的数据是对象类型时,尽可能的使用equals方法来比较。

另外,当整个链表只有1个节点时,判断其是有环的;当其链表中有2个及2个以上的节点时,对其值进行比较,当值相同时就判断为有环,当值不同时,更新指针的位置,单步指针跳一步,双步指针跳两步,直到双步指针跳到null,证明其已经到了链表的尾部,说明是没有环的。

注意:优化,在Node中可以重写equals方法,因为这是链表,比较Node节点即可,但是什么情况下的Node是相等的就需要自己去定义了。

		/**
		 * 自定义equals方法。
		 * 当数据和传入的对象的数据(Integer类型)的data相同时。
		 */
		@Override
		public boolean equals(Object obj) {
			return this.data == ((Node)obj).data;
		}
			// 当值相同时,说明是存在环了
			if(singleStep.equals(doubleStep)) return true;

不再继续比较值,而是比较Node节点是否相同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你家宝宝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值