DirectedCycle.java
package cn.denghanxi.s42;
import cn.denghanxi.s44.DirectedEdge;
import cn.denghanxi.s44.EdgeWeightedDigraph;
import edu.princeton.cs.algs4.Stack;
/**
* 有向图的环检测
*/
public class DirectedCycle {
private boolean[] marked;
private int[] edgeTo;
private Stack<Integer> cycle; //有向环中的所有顶点(如果存在)
private boolean[] onStack; //递归调用栈上的所有顶点
public DirectedCycle(Digraph digraph) {
onStack = new boolean[digraph.v()];
edgeTo = new int[digraph.v()];
marked = new boolean[digraph.v()];
for (int v = 0; v < digraph.v(); v++)
if (!marked[v]) dfs(digraph, v);
}
public DirectedCycle(EdgeWeightedDigraph edgeWeightedDigraph) {
onStack = new boolean[edgeWeightedDigraph.v()];
edgeTo = new int[edgeWeightedDigraph.v()];
marked = new boolean[edgeWeightedDigraph.v()];
for (int v = 0; v < edgeWeightedDigraph.v(); v++)
if (!marked[v]) dfs(edgeWeightedDigraph, v);
}
private void dfs(Digraph digraph, int v) {
onStack[v] = true;
marked[v] = true;
for (int w : digraph.adj(v))
if (this.hasCycle()) return;
else if (!marked[w]) {
edgeTo[w] = v;
dfs(digraph, w);
} else if (onStack[w]) {
cycle = new Stack<>();
for (int x = v; x != w; x = edgeTo[x])
cycle.push(x);
cycle.push(w);
cycle.push(v);
}
onStack[v] = false;
}
private void dfs(EdgeWeightedDigraph edgeWeightedDigraph, int v) {
onStack[v] = true;
marked[v] = true;
for (DirectedEdge edge : edgeWeightedDigraph.adj(v))
if (this.hasCycle()) return;
else if (!marked[edge.to()]) {
edgeTo[edge.to()] = v;
dfs(edgeWeightedDigraph, edge.to());
} else if (onStack[edge.to()]) {
cycle = new Stack<>();
for (int x = v; x != edge.to(); x = edgeTo[x])
cycle.push(x);
cycle.push(edge.to());
cycle.push(v);
}
onStack[v] = false;
}
public boolean hasCycle() {
return cycle != null;
}
public Iterable<Integer> cycle() {
return cycle;
}
}