import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;
/**
* BFS in a Undirected Graph, Connected Graph
* @author Prateek
*/
class UndirectedGraphAPI {
private int numVertices;
private int numEdges;
//Map to maintain adjacency List
private Map
<Integer,ArrayList
<Integer
>> adjList
; // Map to maintain visit status
private Map
<Integer, Boolean
> vistedStatus
;
/*
* Constructor when number of vertices are not known
*/
public UndirectedGraphAPI() {
this.
adjList = new HashMap
<Integer,ArrayList
<Integer
>>(); this.
vistedStatus = new HashMap
<Integer, Boolean
>() ; }
/*
* Constructor when number of vertices are known
*/
public UndirectedGraphAPI(int V) {
this.numVertices = V;
this.
adjList = new HashMap
<Integer,ArrayList
<Integer
>>(V
); this.
vistedStatus = new HashMap
<Integer, Boolean
>(V
) ; }
/**
* Edge in a un-directed graph
*/
protected void addEdge(int src, int dest) {
/*Forward Edge */
ArrayList<Integer> list=adjList.get(src);
if(list==null)
list=new ArrayList<Integer>();
list.add(dest);
adjList.put(src,list);
vistedStatus.put(src, false); //visit status set to false
/* Reverse Edge */
list=adjList.get(dest);
if(list==null)
list=new ArrayList<Integer>();
list.add(src);
adjList.put(dest,list);
vistedStatus.put(dest, false); //visit status set to false
}
/**
* Procedure for Recursive DFS
*/
public void dfs(){
System.
out.
println("Recursive DFS :"); Set
<Map.
Entry<Integer, Boolean
>> entrys
= vistedStatus.
entrySet();
Iterator
<Entry
<Integer, Boolean
>> it
= entrys.
iterator();
while(it.hasNext())
{
boolean isVisited=entry.getValue();
if(!isVisited){
dfsUtil(entry.getKey());
}
}
}
public void dfsUtil(int vertex){
List <Integer
> list
= adjList.
get(vertex
) ;
vistedStatus.put(vertex, true) ;
System.
out.
println(vertex
+ "\t"); int size = list.size();
for(int i = 0;i < size ; i++){
int v=list.get(i);
if(!vistedStatus.get(v))
dfsUtil(v);
}
}
// procedure DFS(Graph,source):
// create a stack S
// push source onto S
// mark source
// while S is not empty:
// pop an item from S into v
// for each edge e incident on v in Graph:
// let w be the other end of e
// if w is not marked:
// mark w
// push w onto S
/**
* Procedure for Iterative DFS using Stack
*/
public void dfsIterative(int startNode){
System.
out.
println("Iterative DFS : "); Stack<Integer> stack = new Stack<Integer>();
stack.push(startNode);
vistedStatus.put(startNode, true);
while(!stack.empty()){
int item=stack.pop();
System.
out.
println("Poped Item : "+ item
);
List<Integer> list = adjList.get(item);
int size= list.size();
for(int j=0; j<size ;j++){
int dest=list.get(j);
if(!vistedStatus.get(dest)){
vistedStatus.put(dest, true);
stack.push(dest);
}
}
}
}
/////======== BREADTH FIRST SEARCH ========/////////
/**
* Desc: Breadth First Search: using queue to visit to all nodes in a connected graph
*/
public void bfs(int startNode)
{
Queue<Integer> bfsQueue = new LinkedList<Integer>();
// stating node visit status set to true
vistedStatus.put(startNode, true);
// start node added to Queue
bfsQueue.add(startNode);
while(!bfsQueue.isEmpty())
{
// Node poped from Queue
int node=bfsQueue.poll();
System.
out.
println("Node poped is : "+node
);
// all connected node list of a give node
List<Integer> list=adjList.get(node);
int size=list.size();
System.
out.
print("Connected Nodes are : "); for(int i=0;i <size; ++i)
{
int adjNode=list.get(i);
System.
out.
print(adjNode
+" "); boolean isVisited=vistedStatus.get(adjNode);
if(!isVisited)
{
vistedStatus.put(adjNode, true);
bfsQueue.add(adjNode);
}
}
System.
out.
println("\n==================="); }
}
public List<Integer> adj(int vertex){
return adjList.get(vertex);
}
public static void main
(String[] args
) { UndirectedGraphAPI g=new UndirectedGraphAPI(4);
// use for bfs and dfs
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 3);
g.addEdge(1, 3);
//g.bfs(0);
//g.dfsIterative(0);
g.dfs();
}
}