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.ArrayList; import java.util.HashSet; import java.util.List; /** * Created_By: zouzhile * Date: 9/23/13 * Time: 5:05 PM */ public class C6_4_GraphSearcher { public 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(one, five); graph.addEdge(two, five); graph.addEdge(two, four); graph.addEdge(two, three); graph.addEdge(three, four); graph.addEdge(four, five); return graph; } // do depth first search public List<Vertex> DFS(Graph graph) { List<Vertex> sequence = new ArrayList<Vertex>(); HashSet<Vertex> candidates = new HashSet<Vertex>(); HashSet<Vertex> visited = new HashSet<Vertex>(); for(Vertex vertex : graph.vertexs()) DFS(graph, vertex, candidates, visited, sequence); return sequence; } public void DFS(Graph graph, Vertex vertex, HashSet<Vertex> candidates, HashSet<Vertex> visited, List<Vertex> sequence) { if(candidates.contains(vertex) || visited.contains(vertex)) return; candidates.add(vertex); for(Vertex adj : graph.adj(vertex)) if(! visited.contains(adj) && ! candidates.contains(adj)) DFS(graph, adj, candidates, visited, sequence); candidates.remove(vertex); sequence.add(vertex); visited.add(vertex); } public List<Vertex> BFS(Graph graph) { List<Vertex> globalSequence = new ArrayList<Vertex>(); HashSet<Vertex> queue = new HashSet<Vertex>(); HashSet<Vertex> visited = new HashSet<Vertex> (); for(Vertex vertex : graph.vertexs()) { List<Vertex> localSequence = this.BFS(graph, vertex, queue, visited); globalSequence.addAll(localSequence); } return globalSequence; } private List<Vertex> BFS(Graph graph, Vertex source, HashSet<Vertex> candidates, HashSet<Vertex> visited) { List<Vertex> localSequence = new ArrayList<Vertex>(); if(! visited.contains(source)) { // Do BFS from current vertex candidates.add(source); while(!candidates.isEmpty()) { // the new unvisited vertexes reachable from current level of vertexes HashSet<Vertex> newCandidates = new HashSet<Vertex>(); // visit the current level of vertexes for(Vertex candidate : candidates) { if(! visited.contains(candidate)) { // add all the unvisited adjacent vertexes of current candidate to new candidates for(Vertex adj : graph.adj(candidate)) if(!visited.contains(adj) && ! candidates.contains(adj)) newCandidates.add(adj); localSequence.add(candidate); // the logic of "visit" current candidate visited.add(candidate); } } candidates.clear(); candidates.addAll(newCandidates); } } return localSequence; } public List<Vertex> BFS(Graph graph, Vertex source) { return this.BFS(graph, source, new HashSet<Vertex>(), new HashSet<Vertex>()); } public static void main(String[] args) { C6_4_GraphSearcher searcher = new C6_4_GraphSearcher(); System.out.println("Undirected Graph - Breadth First Search"); Graph graph = searcher.generateSampleGraph(Graph.UNDIRECTED); for(Vertex vertex : searcher.BFS(graph, graph.getVertex(1))) System.out.println(vertex.getValue() + " "); System.out.println(); System.out.println("Undirected Graph - Depth First Search"); graph = searcher.generateSampleGraph(Graph.UNDIRECTED); for(Vertex vertex : searcher.DFS(graph)) System.out.println(vertex.getValue() + " "); } }