package com.jwetherell.algorithms.graph; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.jwetherell.algorithms.data_structures.Graph; import com.jwetherell.algorithms.data_structures.Graph.Edge; import com.jwetherell.algorithms.data_structures.Graph.Vertex; /** * In graph theory, a connected component (or just component) of an undirected graph is a subgraph in which any two vertices are connected to each * other by paths, and which is connected to no additional vertices in the supergraph. A vertex with no incident edges is itself a connected * component. A graph that is itself connected has exactly one connected component, consisting of the whole graph. * * http://en.wikipedia.org/wiki/Connected_component_(graph_theory) * * @author Justin Wetherell */ public class ConnectedComponents { private ConnectedComponents() { } /** * Finds the connected components subsets of the Graph. * * @param g Graph to find connected components. * @return List of connected components in the Graph. */ public static final > List>> getConnectedComponents(Graph graph) { if (graph == null) throw new IllegalArgumentException("Graph is NULL."); if (graph.getType() != Graph.TYPE.DIRECTED) throw new IllegalArgumentException("Cannot perform a connected components search on a non-directed graph. graph type = "+graph.getType()); final Map,Integer> map = new HashMap,Integer>(); final List>> list = new ArrayList>>(); int c = 0; for (Vertex v : graph.getVertices()) if (map.get(v) == null) visit(map, list, v, c++); return list; } private static final > void visit(Map,Integer> map, List>> list, Vertex v, int c) { map.put(v, c); List> r = null; if (c == list.size()) { r = new ArrayList>(); list.add(r); } else { r = list.get(c); } r.add(v); if (v.getEdges().size() > 0) { boolean found = false; for (Edge e : v.getEdges()) { final Vertex to = e.getToVertex(); if (map.get(to) == null) { visit(map, list, to, c); found = true; } if (found) break; } } } }