算法思路:从开始节点查找,在指定数范围N(如:100个节点)一次获取下一个节点,若有节点为空,则说明链表无循环;否则判断第i个节点和第i+j个节点(i,j < N)的地址是否相同,若相同,则第i个节点是循环起点,程序运行介绍;若无空也找不到循环节点重新设置N去查找。
package test;
public class FindCycledList {
/**
* @param args
*/
public static void main(String[] args) {
int N = 100;// 假设节点个数不大于100,根据实际情况定义
int i,j,n1=90;// 测试节点个数
Node[] node = new Node[n1];
// 初始化链表
for(i = 0; i < n1; i++){
node[i] = new Node(i*5 + 6);
}
for(i =0; i < n1 - 1; i++)
node[i].next = node[i+1];
// 设置循环点
node[n1-1].next = node[6];
for(i = 0; i < N; i++){
for(j = i + 1; j < N; j++){
// System.out.println(i + ":" + j + ":node.a=" + node[i].a + node[i].next.a);
if(null == getNode(node[i],j)){
System.out.println(i + j + "链表无环!");
System.exit(0);
}
if(node[i] == getNode(node[i],j)){
System.out.println("链表有环,循环点是第 " + i + " 个节点!" );
System.exit(0);
}
}
}
}
public static Node getNode(Node node, int n){
for(int i = 0; i < n; i++){
node = node.next;
if(null == node) return null;
}
return node;
}
}
class Node{
int a;
Node next;
Node(int value){
a = value;
}
}
讨论:
1)判断两个节点是否相等,应用“==”操作符判断,若用节点的数值比较,出现相同数值时无法处理;
2)查找第从第i个节点开始的底j个节点,按链表查下去,遇空或下查j个返回。
3)复杂度分析,空间复杂度O(1),时间复杂度O(N^2,N为节点个数);当循环点位置后且环很大的时候效率低。
4)优化方向:为N设置自动增长,当循环点位置后且环很大的时候效率低的解决?