-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
CycleDetection.java
74 lines (61 loc) · 2.72 KB
/
CycleDetection.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package com.jwetherell.algorithms.graph;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.jwetherell.algorithms.data_structures.Graph;
/**
* In computer science, cycle detection or cycle finding is the algorithmic problem of finding a cycle in a sequence of iterated function values.
* <p>
* @see <a href="https://en.wikipedia.org/wiki/Cycle_detection">Cycle Detection (Wikipedia)</a>
* <br>
* @author Justin Wetherell <[email protected]>
*/
public class CycleDetection {
private CycleDetection() { }
/**
* Cycle detection on a unidrected graph.
*
* @param graph Graph
* @return true if a cycle exists
*/
public static <T extends Comparable<T>> boolean detect(Graph<T> graph) {
if (graph == null)
throw new IllegalArgumentException("Graph is NULL.");
if (graph.getType() != Graph.TYPE.UNDIRECTED)
throw new IllegalArgumentException("Graph is needs to be Undirected.");
final Set<Graph.Vertex<T>> visitedVerticies = new HashSet<Graph.Vertex<T>>();
final Set<Graph.Edge<T>> visitedEdges = new HashSet<Graph.Edge<T>>();
final List<Graph.Vertex<T>> verticies = graph.getVertices();
if (verticies == null || verticies.size() == 0)
return false;
// Select the zero-ith element as the root
final Graph.Vertex<T> root = verticies.get(0);
return depthFirstSearch(root, visitedVerticies, visitedEdges);
}
private static final <T extends Comparable<T>> boolean depthFirstSearch(Graph.Vertex<T> vertex, Set<Graph.Vertex<T>> visitedVerticies, Set<Graph.Edge<T>> visitedEdges) {
if (!visitedVerticies.contains(vertex)) {
// Found an unvisited, add to the set
visitedVerticies.add(vertex);
final List<Graph.Edge<T>> edges = vertex.getEdges();
if (edges != null) {
// Follow each unvisited edge, visit the vertex the edge connects to.
for (Graph.Edge<T> edge : edges) {
final Graph.Vertex<T> to = edge.getToVertex();
boolean result = false;
if (to != null && !visitedEdges.contains(edge)) {
visitedEdges.add(edge);
final Graph.Edge<T> recip = new Graph.Edge<T>(edge.getCost(), edge.getToVertex(), edge.getFromVertex());
visitedEdges.add(recip);
result = depthFirstSearch(to, visitedVerticies, visitedEdges);
}
if (result == true)
return result;
}
}
} else {
// visited
return true;
}
return false;
}
}