Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Implementation of BFS using Adjacency Matrix
A simple graph traversal algorithm called Breadth?First Search (BFS) is employed to examine a graph step by step. Before going to an additional stage of vertices, it begins with a certain vertex (source) and checks all of its neighbours in an ordered way. In this blog post, we'll look at three different ways to use an adjacency matrix in CPP methods to construct BFS. We'll go over the algorithm used by each technique, offer relevant code representations, and demonstrate each method's unique results.
Methods Used
Iterative BFS
BFS with Level Information
BFS Shortest Path
Iterative BFS
The first technique employs an adjacency matrix and an iterative methodology to implement BFS. To maintain a record of the vertices that need to be viewed, it makes use of a queue.
Algorithm
Make an array and queue to record viewed vertices.
Enqueue the source vertex and identify it as viewed.
-
Take the following action while there is still a queue:
Display a vertex by dequeuing it using the queue.
Label all nearby unvisited vertices as attended and queue them all up.
Exampple
#include <iostream>
#include <queue>
using namespace std;
// Function to perform Iterative BFS using adjacency matrix
void BFS(int** adjacencyMatrix, int numVertices, int startVertex) {
// Create a boolean array to track visited vertices
bool* visited = new bool[numVertices];
for (int i = 0; i < numVertices; i++) {
visited[i] = false;
}
// Create a queue for BFS traversal
queue<int> q;
// Enqueue the starting vertex and mark it as visited
q.push(startVertex);
visited[startVertex] = true;
while (!q.empty()) {
// Dequeue a vertex from the queue
int currentVertex = q.front();
q.pop();
// Process the current vertex (e.g., print it)
cout << currentVertex << " ";
// Iterate through all vertices
for (int i = 0; i < numVertices; i++) {
// Check if there is an edge between currentVertex and vertex i
// and if vertex i is not visited
if (adjacencyMatrix[currentVertex][i] == 1 && !visited[i]) {
// Enqueue the vertex i and mark it as visited
q.push(i);
visited[i] = true;
}
}
}
delete[] visited;
}
// Example usage
int main() {
int numVertices = 5;
// Create an adjacency matrix for the graph
int** adjacencyMatrix = new int*[numVertices];
for (int i = 0; i < numVertices; i++) {
adjacencyMatrix[i] = new int[numVertices];
}
// Initialize the adjacency matrix (example graph)
adjacencyMatrix[0][1] = 1;
adjacencyMatrix[0][2] = 1;
adjacencyMatrix[1][3] = 1;
adjacencyMatrix[2][3] = 1;
adjacencyMatrix[3][4] = 1;
int startVertex = 0; // Starting vertex for BFS
// Perform BFS traversal
cout << "BFS traversal starting from vertex " << startVertex << ":" << endl;
BFS(adjacencyMatrix, numVertices, startVertex);
// Clean up
for (int i = 0; i < numVertices; i++) {
delete[] adjacencyMatrix[i];
}
delete[] adjacencyMatrix;
return 0;
}
Output
BFS traversal starting from vertex 0: 0 1 2 3 4
BFS with Level Information
The third technique adds level data needed for each vertex to the standard BFS execution. When the degree of each vertex from the initial point is needed, it can be valuable.
Algorithm
Make a queue, a marking array for inspected vertices, and a level?storing array for every vertex.
Change the scale of the initial vertex to 0, enqueue it, and label it as viewed.
-
Take the following action while there is still a queue:
Display a vertex's degree and dequeue it from the queue.
Enqueue all nearby vertices that aren't yet viewed, record them as viewed, and raise their level by one from the present vertex's degree.
Example
#include <iostream>
#include <queue>
#include <vector>
// Function to perform Breadth First Search (BFS) with level information
void bfsWithLevel(const std::vector<std::vector<int>>& graph, int source) {
int numVertices = graph.size();
// Create visited array to keep track of visited vertices
std::vector<bool> visited(numVertices, false);
// Create level array to store the level of each vertex
std::vector<int> level(numVertices, 0);
// Create a queue for BFS traversal
std::queue<int> q;
// Mark the source vertex as visited and enqueue it
visited[source] = true;
q.push(source);
while (!q.empty()) {
// Dequeue a vertex from the queue
int currentVertex = q.front();
q.pop();
// Process the current vertex
std::cout << "Vertex: " << currentVertex << " Level: " << level[currentVertex] << std::endl;
// Explore all adjacent vertices of the current vertex
for (int adjacentVertex = 0; adjacentVertex < numVertices; ++adjacentVertex) {
// If there is an edge from the current vertex to the adjacent vertex and
// the adjacent vertex is not visited yet
if (graph[currentVertex][adjacentVertex] == 1 && !visited[adjacentVertex]) {
// Mark the adjacent vertex as visited
visited[adjacentVertex] = true;
// Update the level of the adjacent vertex
level[adjacentVertex] = level[currentVertex] + 1;
// Enqueue the adjacent vertex
q.push(adjacentVertex);
}
}
}
}
int main() {
// Example usage
std::vector<std::vector<int>> graph = {
{0, 1, 1, 0},
{1, 0, 0, 1},
{1, 0, 0, 1},
{0, 1, 1, 0}
};
bfsWithLevel(graph, 0);
return 0;
}
Output
Vertex: 0 Level: 0 Vertex: 1 Level: 1 Vertex: 2 Level: 1 Vertex: 3 Level: 2
BFS Shortest Path
The fourth technique applies BFS to determine the shortest path in a network symbolised by an adjacency matrix between an initial vertex and the objective vertex. In order to re?create the way, it maintains track of the parent for every vertex.
Algorithm
Make a queue, an array for noting checked out vertices, an array that keeps each vertex's parent, and an array to record the distance from the initial source.
Change the parent of the initial vertex to ?1 and the distance to 0 while marking it as viewed and enqueuing it.
-
Take the following action while there is still a queue:
A vertex can be dequeued from the queue.
Terminate the BFS if the goal's vertex is the dequeued vertex.
Add their parent to the present vertex, assign all nearby unvisited vertices as viewed, queue them up, and modify the distance between them.
Employing the parent array, retrace a route from the desired vertex to the point of origin if the aim vertex has been attained.
Example
#include <iostream>
#include <queue>
#include <vector>
#include <utility> // for std::pair
using namespace std;
void BFS(vector<pair<int, int>>& edgeList, int numVertices, int source) {
vector<bool> visited(numVertices, false);
vector<int> distance(numVertices, 0);
queue<int> q;
// Mark the source vertex as visited and enqueue it
visited[source] = true;
q.push(source);
while (!q.empty()) {
int currentVertex = q.front();
q.pop();
// Process the current vertex (e.g., print its value)
cout << currentVertex << " ";
// Explore all adjacent vertices of the current vertex
for (const auto& edge : edgeList) {
int u = edge.first;
int v = edge.second;
if (u == currentVertex && !visited[v]) {
visited[v] = true;
distance[v] = distance[currentVertex] + 1;
q.push(v);
} else if (v == currentVertex && !visited[u]) {
visited[u] = true;
distance[u] = distance[currentVertex] + 1;
q.push(u);
}
}
}
}
int main() {
int numVertices = 6;
// Example graph representation (edge list)
vector<pair<int, int>> edgeList = {
{0, 1},
{0, 2},
{1, 3},
{2, 3},
{2, 4},
{3, 4},
{3, 5},
{4, 5},
{1, 0}
};
int source = 0; // Starting vertex for BFS
cout << "BFS Traversal: ";
BFS(edgeList, numVertices, source);
return 0;
}
Output
BFS Traversal: 0 1 2 3 4 5
Conclusion
In this post, we looked at three distinct ways to execute Breadth?First Search (BFS) in CPP algorithms implementing an adjacency matrix. Iterative BFS, recursive BFS, BFS with level information, and discovering the shortest path are just a few of the functions that each technique delivers as it traverses a graph stage by stage. You can quickly explore and analyse graphs, carry out level?based functions, and determine the shortest pathways between vertices by comprehending and using these techniques. The strategy chosen will rely on the particular needs and features of the current graph.