判断单链是否循环,并且找出第一个循环节点

简介: <p>介绍</p> <p>    判断单链是否循环,并且找出第一个循环节点。</p> <p>思路</p> <p>    【判断单链是否循环】:如果单链是循环的,那么循环部分就是封闭的。这好比一个田径运动场,当两个人跑步时,开始虽然有一定的间距,但他们迟早会相遇的。</p> <p>顺其自然的我们从中抽取一个数学模型,一个是步长Steps(对应两人刚开始跑步时的间距);一个是判断单链循

介绍

    判断单链是否循环,并且找出第一个循环节点。

思路

    【判断单链是否循环】:如果单链是循环的,那么循环部分就是封闭的。这好比一个田径运动场,当两个人跑步时,开始虽然有一定的间距,但他们迟早会相遇的。

顺其自然的我们从中抽取一个数学模型,一个是步长Steps(对应两人刚开始跑步时的间距);一个是判断单链循环的条件nodeX==nodeY(两人“相遇”)。

    【找出第一个循环节点】:我想过好多其它方法,实现起来都比较难,后来出去骑行了两个小时,回来后就想到借助Hash存储,Hash元素包含判断,结果实现起来既容易,又好懂。

    比如:下图就是一个循环单链,第一个循环节点为3。


package shuai.study.link.circle;

import java.util.HashSet;
import java.util.Set;

class Node {
	String data = null;
	Node nextNode = null;

	public Node(String data, Node nextNode) {
		this.data = data;
		this.nextNode = nextNode;
	}
}

/////////////////////////////////////////////////////////////////////////////////////////

class SingleCircleLink {
	Node firstNode = null;

	Node nodeX = null;
	Node nodeY = null;

	public SingleCircleLink(Node firstNode) {
		this.firstNode = firstNode;

		this.nodeX = firstNode;
		this.nodeY = firstNode;
	}

	public boolean isSingleCircleLink() {
		/*
		 * This while block judge whether this link is circle or not.
		 */
		while (nodeY != null && (nodeY = nodeY.nextNode) != null && nodeX != nodeY) {
			nodeX = nodeX.nextNode;
			nodeY = nodeY.nextNode;
		}

		/*
		 * if Node.next is null, then it illustrates this link isn't circle link.
		 */
		return nodeY != null;
	}

	public void printFirstCircleNode(boolean isSingleCircleLinkFlag) {
		if (isSingleCircleLinkFlag) {
			System.out.println("This is single circle link");

			Set<Node> hashSet = new HashSet<Node>();
			Node nodeZ = firstNode;

			/*
			 * This while block will find the first circle node.
			 */
			while (true) {
				hashSet.add(nodeZ);
				nodeZ = nodeZ.nextNode;

				if (hashSet.contains(nodeZ)) {
					break;
				}
			}

			System.out.println("The first circle node is " + nodeZ.data);
		} else {
			System.out.println("This is not single circle link");
		}
	}
}

/////////////////////////////////////////////////////////////////////////////////////////

/**
 * @author shengshu
 * 
 */
public class SingleCircleLinkApp {
	public static void main(String[] args) {
		Node node6 = new Node("6", null);
		Node node5 = new Node("5", node6);
		Node node4 = new Node("4", node5);
		Node node3 = new Node("3", node4);
		Node node2 = new Node("2", node3);
		Node node1 = new Node("1", node2);

		node6.nextNode = node3;

		SingleCircleLink singleCircleLink = new SingleCircleLink(node1);
		singleCircleLink.printFirstCircleNode(singleCircleLink.isSingleCircleLink());
	}
}


 
相关文章
|
6月前
|
C语言
C 语言实例 - 判断奇数/偶数
C 语言实例 - 判断奇数/偶数。
46 3
|
7天前
|
C#
C# 循环遍历使用
C# 循环遍历使用
24 0
|
7月前
|
Go
怎样判断一个数是否为偶数
怎样判断一个数是否为偶数
44 0
|
8月前
|
前端开发 数据格式
关于三个数组的判断
关于三个数组的判断
34 0
|
10月前
判断数的奇偶性
判断数的奇偶性
51 0
|
10月前
|
人工智能
求数组满足条件个数
求数组满足条件个数
60 0
|
10月前
素数的查找和判断
素数的查找和判断
28 0
|
存储 算法
打印N个数的循环算法和递归算法比较
打印N个数的循环算法和递归算法比较
|
算法
算法 | 妙用递归(顺序&逆序)打印一个数的每一位
- 程序调用自身的编程技巧称为递归( recursion)。递归作为一种算法在程序设计语言中广泛应用 - 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问-题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量 - 递归的能力在于用有限的语句来定义对象的无限集合 - 一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回
180 0
算法 | 妙用递归(顺序&逆序)打印一个数的每一位