-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGraph.java
135 lines (125 loc) · 5.04 KB
/
Graph.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package nonlinear;
import java.util.*;
public class Graph {
List<GraphNode> nodes = new ArrayList<>();
public GraphNode findNode(int data) {
for (GraphNode node : nodes) {
if (node.data == data) {
return node;
}
}
return null;
}
/**
* Performs a Depth First Search(DFS) traversal through all the vertices in the Graph and prints in same line with spaces
* Also avoids iterating the same vertex again by using a Set for tracking visited Vertices
*/
void printDFSTraversal(){
if(nodes.isEmpty()) return;
Set<GraphNode> visited = new HashSet<>();
//iterate over all nodes in the graph, which ensures that disconnected components are also traversed.
for(GraphNode node: nodes){
if(!visited.contains(node)) {
printDFS(node, visited);
}
}
}
private void printDFS(GraphNode node, Set<GraphNode> visited){
if(visited.contains(node)){
return; // Avoid infinite loop for Cyclic graphs
}
visited.add(node);
for(GraphNode gNode: node.neighbours){
printDFS(gNode, visited);
}
System.out.print(node.data + " ");
}
/**
* Performs a Breadth First Search(BFS) traversal through all the vertices in the Graph and prints in same line with spaces
* Also avoids iterating the same vertex again by using a Set for tracking visited Vertices
*/
void printBFSTraversal(){
if(nodes.isEmpty()) return;
Set<GraphNode> visited = new HashSet<>();
//iterate over all nodes in the graph, which ensures that disconnected components are also traversed.
for(GraphNode node: nodes){
if(!visited.contains(node)){
printBFS(node, visited);
}
}
}
private void printBFS(GraphNode node, Set<GraphNode> visited){
Queue<GraphNode> queue = new LinkedList<>();
queue.add(node);
visited.add(node);
while(!queue.isEmpty()){
GraphNode graphNode = queue.poll();
System.out.print(graphNode.data + " ");
for(GraphNode neighbour: graphNode.neighbours){
if(!visited.contains(neighbour)){
visited.add(neighbour);
queue.add(neighbour);
}
}
}
}
/**
* Checks if a cycle exists in a graph.
*
* This method iterates over each node in the graph to determine if there is a cycle. It is designed to work
* on both connected and disconnected graphs. The method uses a Breadth-First Search (BFS) approach
* implemented in the 'checkCycleBFS' method to explore each node and its neighbours.
*
* A cycle is detected if a node is revisited during the BFS traversal, indicating that there is a path
* leading back to an already visited node. This method ensures all nodes are checked including the ones in disconnected components.
*
* @return true if a cycle exists in the graph, false otherwise.
*/
boolean isCycleExists(){
if(nodes.isEmpty()) return false;
Set<GraphNode> visited = new HashSet<>();
//iterate over all nodes in the graph, which ensures that disconnected components are also traversed.
for(GraphNode node: nodes){
if(!visited.contains(node)){
if(checkCycleBFS(node, visited)){
return true;
}
}
}
return false;
}
/**
* Performs a Breadth-First Search (BFS) to detect a cycle starting from a given node.
*
* This method uses BFS to explore the graph from the specified starting node. It keeps track of visited
* nodes to detect if a cycle exists. A cycle is identified if a node is encountered again during the BFS
* traversal that is not the parent of the current node. The method uses a queue for BFS traversal and a
* map to keep track of each node's parent.
*
* @param node The starting node for the BFS traversal.
* @param visited A set of nodes that have already been visited in the BFS traversal.
* @return true if a cycle is detected during the BFS traversal, false otherwise.
*/
private boolean checkCycleBFS(GraphNode node, Set<GraphNode> visited){
Queue<GraphNode> queue = new LinkedList<>();
queue.add(node);
visited.add(node);
Map<GraphNode, GraphNode> parentMap = new HashMap<>();
parentMap.put(node, null);
while(!queue.isEmpty()){
GraphNode graphNode = queue.poll();
for(GraphNode neighbour: graphNode.neighbours){
if(!visited.contains(neighbour)){
visited.add(neighbour);
queue.add(neighbour);
parentMap.put(neighbour, graphNode);
}else{
if(parentMap.get(graphNode) != neighbour){
return true;
}
}
}
}
return false;
}
}