//package gfgGraphs;
import java.util.*;
// this is a directed graph
// if you want undirected graph, add edges from v1->v2 && v2->v1
// use hashmap to construct adjacency list graph in java
class Graph {
HashMap
<Integer, LinkedList
<Integer
>> adj
; // adjacency hashmap
// constructor to construct a graph from the nodes
public Graph(int[] nodes){
adj
= new HashMap
<Integer,LinkedList
<Integer
>>(); visited
= new HashMap
<Integer,Boolean
>();
for(int i=0;i<nodes.length;i++){
adj.put(nodes[i], new LinkedList<Integer>());
visited.put(nodes[i], false);
}
}
// add edge from vertices v1 to v2
void addEdge(int v1,int v2){
adj.get(v1).add(v2);
}
// get neighbors of a vertex
LinkedList<Integer> getNeighbors(int v){
return adj.get(v);
}
// Breadth First Traversal of the Graph (Directed)
// runtime: O(V+E) , no of vertices + edges
static void BFS(Graph g,int n){
Queue<Integer> q = new LinkedList<Integer>();
q.add(n);
while(!q.isEmpty()){
n = q.peek();
g.visited.put(n, true);
Iterator<Integer> i = g.adj.get(q.peek()).iterator(); // peek() returns the head of the queue without removing
q.poll(); // poll() removes and returns the head of the queue
while(i.hasNext() ){
if(!g.visited.get(l)){
g.visited.put(l, true);
q.add(l);
}
}
}
}
// runtime: O(V+E) , no of vertices + edges
static void DFS(Graph g, int n){
if(!g.visited.get(n)){
g.visited.put(n, true);
Iterator<Integer> i = g.adj.get(n).iterator();
while(i.hasNext()){
DFS(g,l);
}
}
}
// returns true even if one cycle is present
// run time: O(V), where V-no of vertices
static boolean isCyclic(Graph g,int n){
if(g.visited.get(n))
return true;
g.visited.put(n, true);
// try statement to return false if
// k throws an exception:No such element exists
try{
k = g.adj.get(n).element();
}
return false;
}
return isCyclic(g, k);
}
/* comments from geeksforgeeks
Nice approach but there is a problem. I don't think isCyclic method works here.
You need to have a cycleDetectionMap just like visited map. Initialize cycleDetectionMap to false
in the constructor. Your isCyclic method should look something like below.
boolean cyclesInGraph(Integer root){
if (!(visitedMap.get(root))) {
visitedMap.put(root, true);
cycleDetectionMap.put(root, true);
List<integer> adjacencyList = adjacencyMap.get(root);
for(int i = 0; i < adjacencyList.size(); i++) {
int current = adjacencyList.get(i);
if(cyclesInGraph(current)){
return true;
} else if (cycleDetectionMap.get(current)) {
return true;
}
}
cycleDetectionMap.put(root, false);
}
return false;
}
Also how about having a reset method in graph to clear visited and cycleDetection maps?
*/
public static void main
(String[] args
) { // TODO Auto-generated method stub
int ar[] = {10,41,62,83};
int ar2[] = {1,2,3,4,5,6,7};
int ar3[] = {1,2,3,4,5,6,7,8,9,10,11,12};
Graph g = new Graph(ar); // BFS graph
Graph g2 = new Graph(ar); // DFS graph
Graph g3 = new Graph(ar);
Graph g4 = new Graph(ar3);
g.addEdge(10, 41);
g.addEdge(10, 62);
g.addEdge(41, 62);
g.addEdge(62, 10);
g.addEdge(62, 41);
g.addEdge(62, 83);
g.addEdge(83, 83);
// System.out.println("BFS Neighbors"+g.getNeighbors(10));
BFS(g,10);
// Depth first traversal
g2.addEdge(10, 41);
g2.addEdge(10, 62);
g2.addEdge(41, 62);
// g2.addEdge(62, 41);
g2.addEdge(62, 10);
g2.addEdge(62, 83);
// g2.addEdge(83, 83);
// g2.addEdge(83, 41);
DFS(g2,62);
// Cyclic graph
g3.addEdge(10, 41);
g3.addEdge(41, 62);
// g3.addEdge(62, 83);
g3.addEdge( 62,10);
//g3.addEdge(83,10);
boolean b = isCyclic(g3,10);
if(b)
System.
out.
println("The graph is cyclic"); else
System.
out.
println("Not a cyclic graph");
g4.addEdge(1,2);
g4.addEdge(1,3);
g4.addEdge(1,4);
g4.addEdge(2,5);
g4.addEdge(2,6);
g4.addEdge(5,9);
g4.addEdge(5,10);
g4.addEdge(4,7);
g4.addEdge(4,8);
g4.addEdge(7,11);
g4.addEdge(7,12);
BFS(g4,1);
Graph g5 = new Graph(ar3);
g5.addEdge(1,2);
g5.addEdge(1,7);
g5.addEdge(1,8);
g5.addEdge(2,3);
g5.addEdge(2,6);
g5.addEdge(3,4);
g5.addEdge(3,5);
g5.addEdge(8,9);
g5.addEdge(8,12);
g5.addEdge(9,10);
g5.addEdge(9,11);
DFS(g5,1);
}
}
Ly9wYWNrYWdlIGdmZ0dyYXBoczsKCmltcG9ydCBqYXZhLnV0aWwuKjsKLy8gdGhpcyBpcyBhIGRpcmVjdGVkIGdyYXBoCi8vIGlmIHlvdSB3YW50IHVuZGlyZWN0ZWQgZ3JhcGgsIGFkZCBlZGdlcyBmcm9tIHYxLT52MiAmJiB2Mi0+djEKLy8gdXNlIGhhc2htYXAgdG8gY29uc3RydWN0IGFkamFjZW5jeSBsaXN0IGdyYXBoIGluIGphdmEKIGNsYXNzIEdyYXBoIHsKCglIYXNoTWFwPEludGVnZXIsIExpbmtlZExpc3Q8SW50ZWdlcj4+IGFkajsgLy8gYWRqYWNlbmN5IGhhc2htYXAKCUhhc2hNYXA8SW50ZWdlcixCb29sZWFuPiB2aXNpdGVkOyAKCQoJLy8gY29uc3RydWN0b3IgdG8gY29uc3RydWN0IGEgZ3JhcGggZnJvbSB0aGUgbm9kZXMKCSBwdWJsaWMgIEdyYXBoKGludFtdIG5vZGVzKXsKCQkgYWRqID0gbmV3IEhhc2hNYXA8SW50ZWdlcixMaW5rZWRMaXN0PEludGVnZXI+PigpOwoJCSB2aXNpdGVkID0gbmV3IEhhc2hNYXA8SW50ZWdlcixCb29sZWFuPigpOwoJCSAKCQkgCgkJZm9yKGludCBpPTA7aTxub2Rlcy5sZW5ndGg7aSsrKXsKCQkJYWRqLnB1dChub2Rlc1tpXSwgbmV3IExpbmtlZExpc3Q8SW50ZWdlcj4oKSk7CgkJCXZpc2l0ZWQucHV0KG5vZGVzW2ldLCBmYWxzZSk7CgkJfQoJfQoJIC8vIGFkZCBlZGdlIGZyb20gdmVydGljZXMgdjEgdG8gdjIKCSB2b2lkIGFkZEVkZ2UoaW50IHYxLGludCB2Mil7CgkJIGFkai5nZXQodjEpLmFkZCh2Mik7CgkgfQoJIAoJIC8vIGdldCBuZWlnaGJvcnMgb2YgYSB2ZXJ0ZXgKCSBMaW5rZWRMaXN0PEludGVnZXI+IGdldE5laWdoYm9ycyhpbnQgdil7CgkJIHJldHVybiBhZGouZ2V0KHYpOwoJIH0KCS8vIEJyZWFkdGggRmlyc3QgVHJhdmVyc2FsIG9mIHRoZSBHcmFwaCAoRGlyZWN0ZWQpCgkvLyBydW50aW1lOiBPKFYrRSkgLCBubyBvZiB2ZXJ0aWNlcyArIGVkZ2VzCgkgc3RhdGljIHZvaWQgQkZTKEdyYXBoIGcsaW50IG4pewoJCSBRdWV1ZTxJbnRlZ2VyPiBxID0gbmV3IExpbmtlZExpc3Q8SW50ZWdlcj4oKTsKCQkgcS5hZGQobik7CgkJIAoJCXdoaWxlKCFxLmlzRW1wdHkoKSl7CgkJCW4gPSBxLnBlZWsoKTsKCQkJU3lzdGVtLm91dC5wcmludChuKyIgIik7CgkJCWcudmlzaXRlZC5wdXQobiwgdHJ1ZSk7CgkJCQoJCQlJdGVyYXRvcjxJbnRlZ2VyPiBpID0gZy5hZGouZ2V0KHEucGVlaygpKS5pdGVyYXRvcigpOyAvLyBwZWVrKCkgcmV0dXJucyB0aGUgaGVhZCBvZiB0aGUgcXVldWUgd2l0aG91dCByZW1vdmluZwoJCQlxLnBvbGwoKTsgLy8gcG9sbCgpIHJlbW92ZXMgYW5kIHJldHVybnMgdGhlIGhlYWQgb2YgdGhlIHF1ZXVlCgkJCXdoaWxlKGkuaGFzTmV4dCgpICl7CgkJCQlJbnRlZ2VyIGwgPSBpLm5leHQoKTsKCQkJCWlmKCFnLnZpc2l0ZWQuZ2V0KGwpKXsJCQkJCQoJCQkJCWcudmlzaXRlZC5wdXQobCwgdHJ1ZSk7CgkJCQkJcS5hZGQobCk7CQkJCQoJCQkJfQoJCQl9CgkJfQoJCSAKCSB9CgkgLy8gcnVudGltZTogTyhWK0UpICwgbm8gb2YgdmVydGljZXMgKyBlZGdlcwoJIHN0YXRpYyB2b2lkIERGUyhHcmFwaCBnLCBpbnQgbil7CgkJIGlmKCFnLnZpc2l0ZWQuZ2V0KG4pKXsKCQkJIFN5c3RlbS5vdXQucHJpbnQobisiICIpOwoJCQkgZy52aXNpdGVkLnB1dChuLCB0cnVlKTsKCQkJIEl0ZXJhdG9yPEludGVnZXI+IGkgPSBnLmFkai5nZXQobikuaXRlcmF0b3IoKTsKCQkJIHdoaWxlKGkuaGFzTmV4dCgpKXsKCQkJCSBJbnRlZ2VyIGwgPSBpLm5leHQoKTsKCQkJCSBERlMoZyxsKTsKCQkJIH0KCQkgfQoJIH0KCQoJIC8vIHJldHVybnMgdHJ1ZSBldmVuIGlmIG9uZSBjeWNsZSBpcyBwcmVzZW50CgkgLy8gcnVuIHRpbWU6IE8oViksIHdoZXJlIFYtbm8gb2YgdmVydGljZXMKCSBzdGF0aWMgYm9vbGVhbiBpc0N5Y2xpYyhHcmFwaCBnLGludCBuKXsKCQkgaWYoZy52aXNpdGVkLmdldChuKSkKCQkJIHJldHVybiB0cnVlOwoJCSBnLnZpc2l0ZWQucHV0KG4sIHRydWUpOwoJCSBJbnRlZ2VyIGsgPSBudWxsOwoJCSAvLyB0cnkgc3RhdGVtZW50IHRvIHJldHVybiBmYWxzZSBpZiAKCQkgLy8gayB0aHJvd3MgYW4gZXhjZXB0aW9uOk5vIHN1Y2ggZWxlbWVudCBleGlzdHMKCQkgdHJ5ewoJCSAgayA9IGcuYWRqLmdldChuKS5lbGVtZW50KCk7CgkJIH0KCQkgY2F0Y2goRXhjZXB0aW9uIGUpewoJCQkgcmV0dXJuIGZhbHNlOwoJCSB9CgkJIHJldHVybiBpc0N5Y2xpYyhnLCBrKTsKCQkgCgkgfQoJIAoJIAoJIC8qIGNvbW1lbnRzIGZyb20gZ2Vla3Nmb3JnZWVrcwoJIE5pY2UgYXBwcm9hY2ggYnV0IHRoZXJlIGlzIGEgcHJvYmxlbS4gSSBkb24ndCB0aGluayBpc0N5Y2xpYyBtZXRob2Qgd29ya3MgaGVyZS4gCgkgWW91IG5lZWQgdG8gaGF2ZSBhIGN5Y2xlRGV0ZWN0aW9uTWFwIGp1c3QgbGlrZSB2aXNpdGVkIG1hcC4gSW5pdGlhbGl6ZSBjeWNsZURldGVjdGlvbk1hcCB0byBmYWxzZSAKCSBpbiB0aGUgY29uc3RydWN0b3IuIFlvdXIgaXNDeWNsaWMgbWV0aG9kIHNob3VsZCBsb29rIHNvbWV0aGluZyBsaWtlIGJlbG93LgoKCWJvb2xlYW4gY3ljbGVzSW5HcmFwaChJbnRlZ2VyIHJvb3QpewoJaWYgKCEodmlzaXRlZE1hcC5nZXQocm9vdCkpKSB7Cgl2aXNpdGVkTWFwLnB1dChyb290LCB0cnVlKTsKCWN5Y2xlRGV0ZWN0aW9uTWFwLnB1dChyb290LCB0cnVlKTsKCUxpc3Q8aW50ZWdlcj4gYWRqYWNlbmN5TGlzdCA9IGFkamFjZW5jeU1hcC5nZXQocm9vdCk7Cglmb3IoaW50IGkgPSAwOyBpIDwgYWRqYWNlbmN5TGlzdC5zaXplKCk7IGkrKykgewoJaW50IGN1cnJlbnQgPSBhZGphY2VuY3lMaXN0LmdldChpKTsKCWlmKGN5Y2xlc0luR3JhcGgoY3VycmVudCkpewoJcmV0dXJuIHRydWU7Cgl9IGVsc2UgaWYgKGN5Y2xlRGV0ZWN0aW9uTWFwLmdldChjdXJyZW50KSkgewoJcmV0dXJuIHRydWU7Cgl9Cgl9CgljeWNsZURldGVjdGlvbk1hcC5wdXQocm9vdCwgZmFsc2UpOwoJfQoJcmV0dXJuIGZhbHNlOwoJfQoKQWxzbyBob3cgYWJvdXQgaGF2aW5nIGEgcmVzZXQgbWV0aG9kIGluIGdyYXBoIHRvIGNsZWFyIHZpc2l0ZWQgYW5kIGN5Y2xlRGV0ZWN0aW9uIG1hcHM/CgkgCgkgKi8KCSAKCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsKCQkvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCgkJaW50IGFyW10gPSB7MTAsNDEsNjIsODN9OwoJCWludCBhcjJbXSA9IHsxLDIsMyw0LDUsNiw3fTsKCQlpbnQgYXIzW10gPSB7MSwyLDMsNCw1LDYsNyw4LDksMTAsMTEsMTJ9OwoJCUdyYXBoIGcgPSBuZXcgR3JhcGgoYXIpOyAvLyBCRlMgZ3JhcGgKCQlHcmFwaCBnMiA9IG5ldyBHcmFwaChhcik7IC8vIERGUyBncmFwaAoJCUdyYXBoIGczID0gbmV3IEdyYXBoKGFyKTsKCQlHcmFwaCBnNCA9IG5ldyBHcmFwaChhcjMpOwoJCQoJCWcuYWRkRWRnZSgxMCwgNDEpOwoJICAgIGcuYWRkRWRnZSgxMCwgNjIpOwoJICAgIGcuYWRkRWRnZSg0MSwgNjIpOwoJICAgIGcuYWRkRWRnZSg2MiwgMTApOwoJICAgIGcuYWRkRWRnZSg2MiwgNDEpOwoJICAgIGcuYWRkRWRnZSg2MiwgODMpOwoJICAgIGcuYWRkRWRnZSg4MywgODMpOwoJICAgIAoJICAgLy8gU3lzdGVtLm91dC5wcmludGxuKCJCRlMgTmVpZ2hib3JzIitnLmdldE5laWdoYm9ycygxMCkpOwoJICAgIFN5c3RlbS5vdXQucHJpbnQoIkJGUzogIik7CgkgICAgQkZTKGcsMTApOwoJICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwoJICAgIAoJICAgIC8vIERlcHRoIGZpcnN0IHRyYXZlcnNhbAoJICAgIAoJICAgIAoJICAgIGcyLmFkZEVkZ2UoMTAsIDQxKTsKCSAgICBnMi5hZGRFZGdlKDEwLCA2Mik7CgkgICAgZzIuYWRkRWRnZSg0MSwgNjIpOwoJIC8vICAgZzIuYWRkRWRnZSg2MiwgNDEpOwoJICAgIGcyLmFkZEVkZ2UoNjIsIDEwKTsKCSAgICAKCSAgICBnMi5hZGRFZGdlKDYyLCA4Myk7CgkvLyAgICBnMi5hZGRFZGdlKDgzLCA4Myk7CgkgIC8vICBnMi5hZGRFZGdlKDgzLCA0MSk7CgkgICAgCgkgICAgU3lzdGVtLm91dC5wcmludCgiREZTOiAiKTsKCSAgICBERlMoZzIsNjIpOwoJICAgIFN5c3RlbS5vdXQucHJpbnRsbigpOwoJICAgIAoJICAgIAoJICAgIC8vIEN5Y2xpYyBncmFwaAoJICAgIGczLmFkZEVkZ2UoMTAsIDQxKTsKCSAgICBnMy5hZGRFZGdlKDQxLCA2Mik7CgkgICAvLyBnMy5hZGRFZGdlKDYyLCA4Myk7CgkgICAgZzMuYWRkRWRnZSggNjIsMTApOwoJICAgIC8vZzMuYWRkRWRnZSg4MywxMCk7CgoJICAgIGJvb2xlYW4gYiA9IGlzQ3ljbGljKGczLDEwKTsKCSAgICBpZihiKQoJICAgIAlTeXN0ZW0ub3V0LnByaW50bG4oIlRoZSBncmFwaCBpcyBjeWNsaWMiKTsKCSAgICBlbHNlCgkgICAgCVN5c3RlbS5vdXQucHJpbnRsbigiTm90IGEgY3ljbGljIGdyYXBoIik7CgkgICAgCgkgICAgZzQuYWRkRWRnZSgxLDIpOwoJICAgIGc0LmFkZEVkZ2UoMSwzKTsKCSAgICBnNC5hZGRFZGdlKDEsNCk7CgkgICAgZzQuYWRkRWRnZSgyLDUpOwoJICAgIGc0LmFkZEVkZ2UoMiw2KTsKCSAgICBnNC5hZGRFZGdlKDUsOSk7CgkgICAgZzQuYWRkRWRnZSg1LDEwKTsKCSAgICBnNC5hZGRFZGdlKDQsNyk7CgkgICAgZzQuYWRkRWRnZSg0LDgpOwoJICAgIGc0LmFkZEVkZ2UoNywxMSk7CgkgICAgZzQuYWRkRWRnZSg3LDEyKTsKCSAgICBTeXN0ZW0ub3V0LnByaW50KCJCRlM6ICIpOwoJICAgIEJGUyhnNCwxKTsKCSAgICBTeXN0ZW0ub3V0LnByaW50bG4oKTsKCSAgICAKCSAgICAKCSAgICBHcmFwaCBnNSA9IG5ldyBHcmFwaChhcjMpOwoJICAgIAoJICAgIGc1LmFkZEVkZ2UoMSwyKTsKCSAgICBnNS5hZGRFZGdlKDEsNyk7CgkgICAgZzUuYWRkRWRnZSgxLDgpOwoJICAgIGc1LmFkZEVkZ2UoMiwzKTsKCSAgICBnNS5hZGRFZGdlKDIsNik7CgkgICAgZzUuYWRkRWRnZSgzLDQpOwoJICAgIGc1LmFkZEVkZ2UoMyw1KTsKCSAgICBnNS5hZGRFZGdlKDgsOSk7CgkgICAgZzUuYWRkRWRnZSg4LDEyKTsKCSAgICBnNS5hZGRFZGdlKDksMTApOwoJICAgIGc1LmFkZEVkZ2UoOSwxMSk7CgkgICAgU3lzdGVtLm91dC5wcmludCgiREZTOiAiKTsKCSAgICBERlMoZzUsMSk7CgkgICAgU3lzdGVtLm91dC5wcmludGxuKCk7CgkgICAgCgl9Cgp9Cg==