package com.interview.algorithms.graph; import com.interview.basics.model.graph.generic.AdjListGraph; import com.interview.basics.model.graph.generic.Graph; import com.interview.basics.model.graph.generic.Vertex; import java.util.HashSet; /** * Created_By: zouzhile * Date: 2/20/14 * Time: 5:49 PM * * Print all the cycles in a directed graph */ public class C6_2_GraphCyclePrinter { public void printGraphCycles(Graph graph) { HashSet<Vertex> visited = new HashSet<Vertex>(); HashSet<Vertex> candidates = new HashSet<Vertex>(); for(Vertex vertex : graph.vertexs()){ if(! visited.contains(vertex) && !candidates.contains(vertex)) DFS(graph, vertex, visited, candidates); } } public void DFS(Graph graph, Vertex vertex, HashSet<Vertex> visited, HashSet<Vertex> candidates) { /* 1 ---] 2 ] /] \ | / | ] | / | 3 | / | / | [ | [ 5 ----] 4 */ candidates.add(vertex); for(Vertex adj : graph.adj(vertex)) { if(candidates.contains(adj)) { // visited nodes may need to revisit to build the cycle // so don't put visited.contains(adj) on the if condition. // an example is node 4 // found cycle printCycle(vertex, adj); } else { adj.setParent(vertex); // build the trace back DFS(graph, adj, visited, candidates); } } candidates.remove(vertex); visited.add(vertex); } private void printCycle(Vertex from, Vertex to) { System.out.print("cycle: "); Vertex vertex = from; while(vertex != to) { System.out.print(vertex.getValue() + " ") ; vertex = vertex.getParent(); } System.out.println(to.getValue()); } public static void main(String[] args) { Graph graph = generateSampleGraph(Graph.DIRECTED); C6_2_GraphCyclePrinter collector = new C6_2_GraphCyclePrinter(); collector.printGraphCycles(graph); } public static Graph generateSampleGraph(int type){ /* 1 ---] 2 ] /] \ | / | ] | / | 3 | / | / | [ | [ 5 ----] 4 */ Graph graph = new AdjListGraph(type); Vertex one = new Vertex(1); Vertex two = new Vertex(2); Vertex three = new Vertex(3); Vertex four = new Vertex(4); Vertex five = new Vertex(5); graph.addEdge(one, two); graph.addEdge(two, five); graph.addEdge(two, three); graph.addEdge(three, four); graph.addEdge(four, two); graph.addEdge(five, one); graph.addEdge(five, four); return graph; } }