Skip to content

Commit 5129386

Browse files
authored
Create README.md
1 parent cc1d703 commit 5129386

File tree

1 file changed

+347
-0
lines changed
  • 23 - Graph Data Structure Problems/02 - BFS Traversal in Graph

1 file changed

+347
-0
lines changed
Lines changed: 347 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,347 @@
1+
<h1 align='center'>BFS - Traversal - In Graph</h1>
2+
3+
**Breadth-First Search (BFS)** is a graph traversal algorithm used to explore nodes and edges in a graph systematically. It starts at a given source node and explores all its neighboring nodes before moving to the neighbors of those neighbors, essentially performing a level-order traversal.
4+
5+
BFS is particularly useful for:
6+
1. **Finding the shortest path** in an unweighted graph.
7+
2. Checking graph connectivity.
8+
3. Solving problems like bipartite graph detection, maze problems, and more.
9+
10+
#### **Characteristics of BFS**:
11+
- Uses a **queue** to keep track of nodes to visit.
12+
- Traverses the graph **level by level**.
13+
- Ensures that all nodes at a given "depth" from the source node are visited before moving to the next depth.
14+
15+
16+
### **Example of BFS**
17+
18+
**Graph**:
19+
Let's consider the following undirected graph:
20+
21+
```
22+
0
23+
/ \
24+
1 2
25+
/ \ \
26+
3 4 5
27+
```
28+
29+
#### BFS Traversal:
30+
If we start BFS from node `0`, the order of traversal will be:
31+
```
32+
Level 0: 0
33+
Level 1: 1, 2
34+
Level 2: 3, 4, 5
35+
```
36+
37+
So the BFS traversal order is: `0 -> 1 -> 2 -> 3 -> 4 -> 5`.
38+
39+
40+
### **Approach to Implement BFS**
41+
42+
1. **Initialize a Queue**:
43+
- Use a queue to keep track of the nodes to be visited. Push the starting node into the queue.
44+
45+
2. **Visited Array**:
46+
- Maintain a `visited` array to mark nodes that have already been visited to avoid revisiting them.
47+
48+
3. **Process Nodes**:
49+
- While the queue is not empty:
50+
- Pop the front node from the queue.
51+
- Process it (e.g., print it or store it in the result).
52+
- Push all its unvisited neighbors into the queue and mark them as visited.
53+
54+
4. **End Traversal**:
55+
- Once the queue is empty, BFS is complete.
56+
57+
### **Implementation of BFS**
58+
59+
Here’s how BFS can be implemented for a graph using an adjacency list:
60+
61+
```cpp
62+
#include <iostream>
63+
#include <vector>
64+
#include <queue>
65+
66+
using namespace std;
67+
68+
// Graph class definition
69+
class Graph {
70+
public:
71+
vector<vector<int>> adjacencyList;
72+
73+
// Constructor to initialize the adjacency list
74+
Graph(int totalNodes) {
75+
adjacencyList.resize(totalNodes);
76+
}
77+
78+
// Function to add an edge to the graph
79+
void addEdge(int sourceNode, int destinationNode, bool isDirected = false) {
80+
adjacencyList[sourceNode].push_back(destinationNode);
81+
if (!isDirected) {
82+
adjacencyList[destinationNode].push_back(sourceNode);
83+
}
84+
}
85+
86+
// Function to perform BFS traversal
87+
void bfs(int startNode) {
88+
vector<bool> visited(adjacencyList.size(), false); // Visited array
89+
queue<int> q; // Queue for BFS
90+
91+
// Start BFS from the startNode
92+
visited[startNode] = true;
93+
q.push(startNode);
94+
95+
cout << "BFS Traversal: ";
96+
97+
while (!q.empty()) {
98+
int currentNode = q.front();
99+
q.pop();
100+
101+
// Process the current node (e.g., print it)
102+
cout << currentNode << " ";
103+
104+
// Visit all unvisited neighbors
105+
for (int neighbor : adjacencyList[currentNode]) {
106+
if (!visited[neighbor]) {
107+
visited[neighbor] = true;
108+
q.push(neighbor);
109+
}
110+
}
111+
}
112+
cout << endl;
113+
}
114+
};
115+
116+
int main() {
117+
int totalNodes = 6;
118+
119+
// Create the graph
120+
Graph g(totalNodes);
121+
122+
// Add edges to the graph
123+
g.addEdge(0, 1);
124+
g.addEdge(0, 2);
125+
g.addEdge(1, 3);
126+
g.addEdge(1, 4);
127+
g.addEdge(2, 5);
128+
129+
// Perform BFS traversal starting from node 0
130+
g.bfs(0);
131+
132+
return 0;
133+
}
134+
```
135+
136+
### Source Code Explanation
137+
Here’s a **line-by-line explanation** of the BFS traversal code with examples and the corresponding output:
138+
139+
### **Code Explanation**
140+
141+
```cpp
142+
#include <iostream>
143+
#include <vector>
144+
#include <queue>
145+
using namespace std;
146+
```
147+
148+
- **Purpose**: These are essential header files.
149+
- `#include <iostream>`: For input/output operations.
150+
- `#include <vector>`: For using the adjacency list as a vector of vectors.
151+
- `#include <queue>`: BFS requires a queue to manage nodes to visit.
152+
153+
154+
```cpp
155+
class Graph {
156+
public:
157+
vector<vector<int>> adjacencyList;
158+
```
159+
160+
- **Explanation**:
161+
- A class named `Graph` is defined.
162+
- `adjacencyList`: A vector of vectors to represent the graph. Each index `i` holds a list of nodes connected to node `i`.
163+
164+
165+
166+
```cpp
167+
Graph(int totalNodes) {
168+
adjacencyList.resize(totalNodes);
169+
}
170+
```
171+
172+
- **Explanation**:
173+
- Constructor initializes the graph with `totalNodes` nodes.
174+
- Resizes the `adjacencyList` to ensure every node has an associated list.
175+
176+
177+
178+
```cpp
179+
void addEdge(int sourceNode, int destinationNode, bool isDirected = false) {
180+
adjacencyList[sourceNode].push_back(destinationNode);
181+
if (!isDirected) {
182+
adjacencyList[destinationNode].push_back(sourceNode);
183+
}
184+
}
185+
```
186+
187+
- **Purpose**: Adds edges between nodes.
188+
- **Parameters**:
189+
- `sourceNode`: Start of the edge.
190+
- `destinationNode`: End of the edge.
191+
- `isDirected`: If `true`, the edge is one-way; otherwise, it is bidirectional.
192+
- **How it works**:
193+
- Adds `destinationNode` to `sourceNode`'s adjacency list.
194+
- If the graph is undirected, it also adds `sourceNode` to `destinationNode`'s adjacency list.
195+
196+
197+
198+
```cpp
199+
void bfs(int startNode) {
200+
vector<bool> visited(adjacencyList.size(), false);
201+
queue<int> q;
202+
```
203+
204+
- **Explanation**:
205+
- Initializes a `visited` array to track visited nodes.
206+
- A queue `q` is used to manage BFS traversal.
207+
208+
209+
210+
```cpp
211+
visited[startNode] = true;
212+
q.push(startNode);
213+
```
214+
215+
- **Explanation**:
216+
- Marks the `startNode` as visited.
217+
- Pushes the `startNode` into the queue to begin traversal.
218+
219+
220+
221+
```cpp
222+
cout << "BFS Traversal: ";
223+
```
224+
225+
- **Explanation**: Outputs a label for the BFS traversal results.
226+
227+
228+
```cpp
229+
while (!q.empty()) {
230+
int currentNode = q.front();
231+
q.pop();
232+
```
233+
234+
- **Explanation**:
235+
- The loop continues until the queue is empty.
236+
- Retrieves the front node of the queue (`currentNode`) and removes it.
237+
238+
239+
240+
```cpp
241+
cout << currentNode << " ";
242+
```
243+
244+
- **Explanation**: Prints the `currentNode` to show its processing in BFS.
245+
246+
247+
```cpp
248+
for (int neighbor : adjacencyList[currentNode]) {
249+
if (!visited[neighbor]) {
250+
visited[neighbor] = true;
251+
q.push(neighbor);
252+
}
253+
}
254+
}
255+
cout << endl;
256+
}
257+
```
258+
259+
- **Explanation**:
260+
- Iterates through all neighbors of the `currentNode`.
261+
- If a neighbor has not been visited:
262+
- Marks it as visited.
263+
- Adds it to the queue for future processing.
264+
265+
266+
267+
```cpp
268+
int main() {
269+
int totalNodes = 6;
270+
271+
// Create the graph
272+
Graph g(totalNodes);
273+
```
274+
275+
- **Explanation**:
276+
- Declares `totalNodes` as `6`.
277+
- Creates a graph object `g` with `6` nodes.
278+
279+
280+
```cpp
281+
g.addEdge(0, 1);
282+
g.addEdge(0, 2);
283+
g.addEdge(1, 3);
284+
g.addEdge(1, 4);
285+
g.addEdge(2, 5);
286+
```
287+
288+
- **Explanation**:
289+
- Adds edges to the graph:
290+
- Node `0` is connected to nodes `1` and `2`.
291+
- Node `1` is connected to nodes `3` and `4`.
292+
- Node `2` is connected to node `5`.
293+
294+
295+
```cpp
296+
g.bfs(0);
297+
298+
return 0;
299+
}
300+
```
301+
302+
- **Explanation**:
303+
- Calls `bfs(0)` to perform BFS starting from node `0`.
304+
- Returns `0` to indicate successful program execution.
305+
306+
307+
### **Graph Representation**
308+
309+
The graph looks like this:
310+
311+
```
312+
0
313+
/ \
314+
1 2
315+
/ \ \
316+
3 4 5
317+
```
318+
319+
320+
### **Output**
321+
322+
```
323+
BFS Traversal: 0 1 2 3 4 5
324+
```
325+
326+
- **Explanation**:
327+
- BFS starts at node `0`.
328+
- Visits nodes `1` and `2` (neighbors of `0`).
329+
- Then visits nodes `3` and `4` (neighbors of `1`) and finally node `5` (neighbor of `2`).
330+
331+
### **Time Complexity**
332+
333+
1. **Adjacency List Traversal**:
334+
- Each edge is visited once: **O(E)**.
335+
- Each node is visited once: **O(V)**.
336+
337+
Total Time Complexity: **O(V + E)**.
338+
339+
340+
### **Space Complexity**
341+
342+
1. **Visited Array**: Stores the state of each node: **O(V)**.
343+
2. **Queue**: Can hold up to **O(V)** nodes.
344+
3. **Adjacency List**: Takes **O(V + E)**.
345+
346+
Total Space Complexity: **O(V + E)**.
347+

0 commit comments

Comments
 (0)