package com.interview.graph; import java.util.HashSet; import java.util.Set; /** * http://www.geeksforgeeks.org/detect-cycle-in-a-graph/ */ public class CycleInDirectedGraph { public boolean hasCycle(Graph<Integer> graph) { Set<Vertex<Integer>> whiteSet = new HashSet<>(); Set<Vertex<Integer>> graySet = new HashSet<>(); Set<Vertex<Integer>> blackSet = new HashSet<>(); for (Vertex<Integer> vertex : graph.getAllVertex()) { whiteSet.add(vertex); } while (whiteSet.size() > 0) { Vertex<Integer> current = whiteSet.iterator().next(); if(dfs(current, whiteSet, graySet, blackSet)) { return true; } } return false; } private boolean dfs(Vertex<Integer> current, Set<Vertex<Integer>> whiteSet, Set<Vertex<Integer>> graySet, Set<Vertex<Integer>> blackSet ) { //move current to gray set from white set and then explore it. moveVertex(current, whiteSet, graySet); for(Vertex<Integer> neighbor : current.getAdjacentVertexes()) { //if in black set means already explored so continue. if (blackSet.contains(neighbor)) { continue; } //if in gray set then cycle found. if (graySet.contains(neighbor)) { return true; } if(dfs(neighbor, whiteSet, graySet, blackSet)) { return true; } } //move vertex from gray set to black set when done exploring. moveVertex(current, graySet, blackSet); return false; } private void moveVertex(Vertex<Integer> vertex, Set<Vertex<Integer>> sourceSet, Set<Vertex<Integer>> destinationSet) { sourceSet.remove(vertex); destinationSet.add(vertex); } public static void main(String args[]){ Graph<Integer> graph = new Graph<>(true); graph.addEdge(1, 2); graph.addEdge(1, 3); graph.addEdge(2, 3); graph.addEdge(4, 1); graph.addEdge(4, 5); graph.addEdge(5, 6); graph.addEdge(6, 4); CycleInDirectedGraph cdg = new CycleInDirectedGraph(); System.out.println(cdg.hasCycle(graph)); } }