Graph Lab Manual
Graph Lab Manual
Musarrat Abdullah
Designation: Associate professor
Course: Data structures and Algorithms
Lab manual no:
Lab title: Graphs
ADJACENCY LIST
1. Introduction
Definition: In Data Structures and Algorithms (DSA), an adjacency list is a common way to represent a
graph. It's particularly useful for efficiently handling sparse graphs. The adjacency list consists of an array
(or a list) of lists. Each element of the main array represents a vertex, and each corresponding sub list
contains the neighbors (or adjacent vertices) of that vertex.
Analogy: Imagine you have a group of friends, and you want to keep track of who is friends with whom.
Each person is a node, and a friendship between two people is an edge.
1
2. Key Operations
Adding an Edge:
To add an edge between two vertices u and v, you append v to the adjacency list of u and vice
versa (for undirected graphs).
-Time Complexity (O (1)) - This operation is constant time because appending to a list is a
constant-time operation.
Removing an Edge:
To remove an edge between two vertices and v, you remove v from the adjacency list of u and
vice versa (for undirected graphs).
- Time Complexity: (O(V)) - In the worst case, you may need to search for v in the adjacency list
of u, which can take (O(V)) time, where V is the number of vertices.
Adding a Vertex:
To add a vertex u, you simply create a new entry in the adjacency list with an empty list.
- Time Complexity: (O (1)) - This operation is constant time because it involves creating a new
entry in a data structure.
Removing a Vertex:
To remove a vertex u, you delete its entry from the adjacency list and also remove u from the
adjacency lists of all other vertices.
- Time Complexity: (O (V + E)) - Removing a vertex involves deleting u from V adjacency lists
(which takes (O(V)) time) and searching and removing u from E edges (which also takes (O(E))
time).
3. Implementation
In an array-based implementation, we use an array where each element is a list to store the adjacent
vertices of each vertex. The index of the array represents the vertex, and the list at each index contains its
adjacent vertices. To add an edge, we append the destination vertex to the list of the source vertex. For
undirected graphs, we add the source vertex to the list of the destination vertex as well. Removing an
2
edge involves removing the destination vertex from the source vertex's list and vice versa for undirected
graphs. This method is efficient for fixed-size graphs but can be less flexible for dynamic scenarios.
In a linked list-based implementation, we use a list where each element is a linked list to store the
adjacent vertices of each vertex. Each vertex is represented by a node, and each node points to another
linked list containing its adjacent vertices. To add an edge, we add a node for the destination vertex to the
source vertex's linked list, and for undirected graphs, we also add a node for the source vertex to the
destination vertex's linked list. Removing an edge requires traversing the linked list to find and remove
the node. This method offers more flexibility for dynamic graphs but can be slower due to the need for
traversal operations.
SAMPLE CODES
Write a program which takes input of an undirected or directed graph as an adjacency list and find
out whether there are any loops in the graph.
#include <iostream>
using namespace std;
struct edge;
struct node {
char name;
node *next;
edge *adj;
} *start = NULL;
struct edge {
char dest;
edge *link;
};
int main() {
int choice;
char node, origin, destin;
while (1) {
cout << "1. Insert a node\n";
3
cout << "2. Insert an edge\n";
cout << "3. Delete a node\n";
cout << "4. Delete an edge\n";
cout << "5. Display\n";
cout << "6. Find successors\n";
cout << "7. Find predecessors\n";
cout << "8. Exit\n";
cout << "Enter your choice: ";
cin >> choice;
switch (choice) {
case 1:
cout << "\nEnter a node to be inserted: ";
cin >> node;
insert_node(node);
break;
case 2:
cout << "\nEnter an edge's origin to be inserted: ";
cin >> origin;
cout << "\nEnter an edge's destination to be inserted: ";
cin >> destin;
insert_edge(origin, destin);
break;
case 3:
cout << "\nEnter a node to be deleted: ";
cin >> node;
delete_node(node); // This fn deletes the node from header node list.
delnode_edge(node); // This fn deletes all edges coming to this node.
break;
case 4:
cout << "\nEnter an edge's origin to be deleted: ";
cin >> origin;
cout << "\nEnter an edge's destination to be deleted: ";
cin >> destin;
del_edge(origin, destin);
break;
case 5:
display();
break;
case 6:
cout << "\nEnter the node to find successors: ";
cin >> node;
successors(node);
break;
case 7:
cout << "\nEnter the node to find predecessors: ";
cin >> node;
predecessors(node);
break;
case 8:
exit(1);
4
break;
default:
cout << "\nWrong choice!\n";
break;
}
}
return 0;
}
if (start == NULL) {
start = tmp;
return;
}
ptr = start;
ptr->next = tmp;
}
void delete_node(char u) {
node *tmp, *q;
if (start->name == u) {
tmp = start;
start = start->next; /* first element deleted */
delete tmp;
return;
}
q = start;
q = q->next;
5
}
void delnode_edge(char u) {
node *ptr;
edge *q, *tmp;
ptr = start;
q = ptr->adj;
q = q->link;
}
ptr = ptr->next;
}
}
locu = find(u);
6
locv = find(v);
if (locu == NULL) {
cout << "\nSource node not present, first insert node " << u;
return;
}
if (locv == NULL) {
cout << "\nDestination node not present, first insert node " << v;
return;
}
ptr->link = tmp;
}
}
loc = NULL;
return loc;
}
locu = find(u);
7
if (locu == NULL) {
cout << "\nSource node not present\n";
return;
}
q = locu->adj;
q = q->link;
}
void display() {
node *ptr;
edge *q;
ptr = start;
while (q != NULL) {
cout << q->dest << " ";
q = q->link;
}
8
ptr = ptr->next;
}
}
void successors(char u) {
node* loc = find(u);
bool hasoutdegree = false;
if(loc == NULL){
cout<<"Node not present in the graph"<<endl;
}
cout<<"Successors of the node "<<u<<" are : ";
edge* q = loc->adj;
while(q !=NULL){
cout<<q->dest<<" ";
hasoutdegree = true;
q = q->link;
}
if(!hasoutdegree){
cout<<"None";
}
cout<<endl;
void predecessors(char u) {
node *ptr;
edge *q;
ptr = start;
bool hasIndegree = false;
cout << "Predecessors of node " << u << " are: ";
while (ptr != NULL) {
q = ptr->adj;
while (q != NULL) {
if (q->dest == u) {
cout << ptr->name << " ";
hasIndegree = true;
}
q = q->link;
}
ptr = ptr->next;
}
if (!hasIndegree) {
cout << "None";
}
cout << endl;
}
9
Write a program to find the indegree and outdegree of a node in a directed graph using adjacency
list.
#include <iostream>
using namespace std;
struct edge;
struct node {
char name;
node *next;
edge *adj;
} *start = NULL;
struct edge {
char dest;
edge *link;
};
int main() {
int choice;
char node, origin, destin;
while (1) {
cout << "1. Insert a node\n";
cout << "2. Insert an edge\n";
cout << "3. Delete a node\n";
cout << "4. Delete an edge\n";
cout << "5. Display\n";
cout << "6. Display Indegrees of a node\n";
cout << "7. Display Outdegrees of a node\n";
cout << "8. Exit\n";
switch (choice) {
case 1:
cout << "\nEnter a node to be inserted: ";
10
cin >> node;
insert_node(node);
break;
case 2:
cout << "\nEnter an edge's origin to be inserted: ";
cin >> origin;
cout << "\nEnter an edge's destination to be inserted: ";
cin >> destin;
insert_edge(origin, destin);
break;
case 3:
cout << "\nEnter a node to be deleted: ";
cin >> node;
delete_node(node); // This fn deletes the node from header node list.
delnode_edge(node); // This fn deletes all edges coming to this node.
break;
case 4:
cout << "\nEnter an edge's origin to be deleted: ";
cin >> origin;
cout << "\nEnter an edge's destination to be deleted: ";
cin >> destin;
del_edge(origin, destin);
break;
case 5:
display();
break;
case 6:
cout << "\nEnter a node : ";
cin >> node;
indegree(node);
break;
case 7:
cout << "\nEnter a node: ";
cin >> node;
outdegree(node);
break;
case 8:
exit(1);
break;
default:
cout << "\nWrong choice!\n";
break;
}
}
return 0;
}
11
tmp->name = node_name;
tmp->next = NULL;
tmp->adj = NULL;
if (start == NULL) {
start = tmp;
return;
}
ptr = start;
ptr->next = tmp;
}
void delete_node(char u) {
node *tmp, *q;
if (start->name == u) {
tmp = start;
start = start->next; /* first element deleted */
delete tmp;
return;
}
q = start;
q = q->next;
}
void delnode_edge(char u) {
node *ptr;
edge *q, *tmp;
12
ptr = start;
q = ptr->adj;
q = q->link;
}
ptr = ptr->next;
}
}
locu = find(u);
locv = find(v);
if (locu == NULL) {
cout << "\nSource node not present, first insert node " << u;
return;
}
if (locv == NULL) {
cout << "\nDestination node not present, first insert node " << v;
return;
}
13
tmp->dest = v;
tmp->link = NULL;
ptr->link = tmp;
}
loc = NULL;
return loc;
}
locu = find(u);
if (locu == NULL) {
cout << "\nSource node not present\n";
return;
}
14
q = locu->adj;
q = q->link;
}
void display() {
node *ptr;
edge *q;
ptr = start;
while (q != NULL) {
cout << q->dest << " ";
q = q->link;
}
void indegree(char u ){
node *ptr;
edge *q;
ptr = start;
bool hasIndegree = false;
cout << "Nodes contributing to the indegree of node " << u << " are: ";
while (ptr != NULL) {
15
q = ptr->adj;
while (q != NULL) {
if (q->dest == u) {
cout << ptr->name << " ";
hasIndegree = true;
}
q = q->link;
}
ptr = ptr->next;
}
if (!hasIndegree) {
cout << "None";
}
cout << endl;
}
Write a program to find out the number of source nodes and sink nodes in an undirected graph
using adjacency list.
#include <iostream>
using namespace std;
16
void insert_node(int node_name);
void delete_node(int u);
void insert_edge(int u, int v);
void del_edge(int u, int v);
void display();
int indegree(int u);
int outdegree(int u);
void sourcesink();
int main() {
int choice;
int node, origin, destin;
while (1) {
cout << "1. Insert a node\n";
cout << "2. Insert an edge\n";
cout << "3. Delete a node\n";
cout << "4. Delete an edge\n";
cout << "5. Display\n";
cout << "6. Display Indegrees of a node\n";
cout << "7. Display Outdegrees of a node\n";
cout << "8. Exit\n";
cout << "9. Check source and sink nodes\n";
cout << "Enter your choice: ";
cin >> choice;
switch (choice) {
case 1:
cout << "\nEnter a node to be inserted: ";
cin >> node;
insert_node(node);
break;
case 2:
cout << "\nEnter an edge's origin to be inserted: ";
cin >> origin;
cout << "\nEnter an edge's destination to be inserted: ";
cin >> destin;
insert_edge(origin, destin);
break;
case 3:
cout << "\nEnter a node to be deleted: ";
cin >> node;
delete_node(node);
break;
case 4:
cout << "\nEnter an edge's origin to be deleted: ";
cin >> origin;
cout << "\nEnter an edge's destination to be deleted: ";
17
cin >> destin;
del_edge(origin, destin);
break;
case 5:
display();
break;
case 6:
cout << "\nEnter a node: ";
cin >> node;
cout << "Indegree of node " << node << " is " << indegree(node) << endl;
break;
case 7:
cout << "\nEnter a node: ";
cin >> node;
cout << "Outdegree of node " << node << " is " << outdegree(node) << endl;
break;
case 8:
exit(1);
break;
case 9:
sourcesink();
break;
default:
cout << "\nWrong choice!\n";
break;
}
}
return 0;
}
void delete_node(int u) {
int index = find(u);
if (index == -1) {
cout << "Node not found" << endl;
return;
}
18
for (int i = index; i < node_count - 1; i++) {
nodes[i] = nodes[i + 1];
for (int j = 0; j < node_count; j++) {
graph[j][i] = graph[j][i + 1];
graph[i][j] = graph[i + 1][j];
}
}
node_count--;
}
graph[origin][destin] = 1;
}
graph[origin][destin] = 0;
}
void display() {
for (int i = 0; i < node_count; i++) {
cout << nodes[i] << " -> ";
for (int j = 0; j < node_count; j++) {
if (graph[i][j]) {
cout << nodes[j] << " ";
}
}
cout << endl;
}
}
19
}
}
return -1;
}
int indegree(int u) {
int index = find(u);
if (index == -1) {
return -1;
}
int count = 0;
for (int i = 0; i < node_count; i++) {
if (graph[i][index]) {
count++;
}
}
return count;
}
int outdegree(int u) {
int index = find(u);
if (index == -1) {
return -1;
}
int count = 0;
for (int i = 0; i < node_count; i++) {
if (graph[index][i]) {
count++;
}
}
return count;
}
void sourcesink() {
int source = 0;
int sink = 0;
20
}
}
cout << "The source nodes in this graph are " << source << endl;
cout << "The sink nodes in this graph are " << sink << endl;
}
ADJENCY MARTICE
1. Introduction
Definition: The Adjacency Matrix is a 2D array (matrix) where each cell on index (i,j) stores
information about the edge from vertex i to vertex j.
Analogy: Imagine you have a group of friends: Alice, Bob, Charlie, and Diana. You want to track their
friendships using an adjacency matrix:
21
2. Key Operations
Adding an Edge:
Set (A[u][v] = 1) for an unweighted graph, or (A[u][v] = w) for a weighted graph (where (w) is
the weight of the edge).
Removing an Edge:
Set (A[u][v] = 0) for an unweighted graph, or (A[u][v] = infinity) for a weighted graph.
Adding a Vertex:
Extend the adjacency matrix by one row and one column, initializing entries as needed.
Removing a Vertex:
Delete the corresponding row and column from the adjacency matrix, shifting remaining vertices
as necessary.
3. Implementation
It is very easy and simple to implement an adjacency matrix for a graph there are certain steps given
below that you need to follow:
SAMPLE CODES
Write a function to check if there exists an edge between two vertices u and v in the adjacency
matrix.
#include <iostream>
using namespace std;
int adjMatrix[MAX_VERTICES][MAX_VERTICES];
int V;
22
bool isEdge(int u, int v) {
if (u < 0 || u >= V || v < 0 || v >= V)
return false;
return (adjMatrix[u][v] != 0);
}
void displayMatrix() {
cout << "Adjacency Matrix:" << endl;
for (int i = 0; i < V; ++i) {
for (int j = 0; j < V; ++j) {
cout << adjMatrix[i][j] << " ";
}
cout << endl;
}
}
int main() {
V = 4;
addEdge(0, 1);
addEdge(1, 2);
addEdge(2, 3);
addEdge(3, 0);
displayMatrix();
deleteEdge(1, 2);
deleteEdge(3, 0);
return 0;
}
23
Write a function to detect if a directed graph represented by an adjacency matrix has any
cycles.
#include <iostream>
using namespace std;
#define MAX 20
int adj[MAX][MAX];
bool visited[MAX];
bool recursion_stack[MAX];
int n; // denotes number of nodes in the graph
bool dfs(int v) {
if (!visited[v]) {
visited[v] = true;
recursion_stack[v] = true;
bool hasCycle() {
for (int i = 1; i <= n; ++i) {
visited[i] = false;
recursion_stack[i] = false;
}
max_edges = n * (n - 1);
if (hasCycle())
cout << "\nThe graph has cycles.\n";
else
cout << "\nThe graph does not have cycles.\n";
return 0;
}
Write a program to calculate and print the transitive closure of a directed graph using its
adjacency matrix.
#include <iostream>
using namespace std;
#define MAX 20
int adj[MAX][MAX];
25
int transitive_closure[MAX][MAX];
int n; // number of nodes in the graph
void calculate_transitive_closure() {
// Initialize transitive closure with the adjacency matrix
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
transitive_closure[i][j] = adj[i][j];
}
}
void display_transitive_closure() {
cout << "\nTransitive Closure:\n";
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
cout << transitive_closure[i][j] << " ";
}
cout << endl;
}
}
int main() {
int max_edges, origin, destin;
max_edges = n * (n - 1);
26
break;
cout << "\nEnter edge destination " << i << " (00 to quit): ";
cin >> destin;
if (destin == 0)
break;
return 0;
}
GRAPHS TRAVERSAL
1. Introduction
Definition: To traverse a Graph means to start in one vertex, and go along the edges to visit other
vertices until all vertices, or as many as possible, have been visited.
27
The two most common ways a Graph can be traversed are:
Depth-first search is an algorithm for traversing or searching tree or graph data structures. The
algorithm starts at the root node (selecting some arbitrary node as the root node in the case of a
graph) and explores as far as possible along each branch before backtracking.
Breadth First Search (BFS) is a fundamental graph traversal algorithm. It involves visiting all the
connected nodes of a graph in a level-by-level manner.
Analogy:
Imagine you're exploring a maze, starting at a specific point. In DFS, you follow a path as far as
you can before backtracking. It's like entering a corridor (edge) and exploring it fully (going
deep) before considering other corridors branching off from the same point. This method ensures
thorough exploration of one path before moving on to explore others.
28
Breadth-First Search (BFS) Analogy:
Contrastingly, BFS explores the maze level by level. You start at the entrance (vertex) and explore
all adjacent corridors (edges) before moving on to corridors further away. It's akin to exploring all
possible paths of a certain length before moving to longer paths, ensuring you cover all
possibilities at the current depth level before progressing.
2. Key Operations
Graph traversal algorithms, such as Breadth-First Search (BFS) and Depth-First Search (DFS), perform
several key operations to explore and analyze graphs. Here are the key operations involved in graph
traversal:
Visit a Vertex:
During traversal, each vertex is visited exactly once. Visiting a vertex involves marking it as
visited or processing it based on the traversal algorithm's requirements.
29
Traversal algorithms can be used to find paths between two vertices or determine the shortest path
from a starting vertex to all other vertices in unweighted graphs. BFS is particularly suitable for
finding the shortest path in unweighted graphs due to its level-wise exploration.
Cycle Detection:
In directed and undirected graphs, traversal algorithms can detect cycles by observing revisited
vertices or back edges during traversal.
3. Implementation
DFS Using a Stack
Depth-First Search (DFS) is a graph traversal method that explores as far down a branch as possible
before backtracking. It can be implemented using a stack, which helps in keeping track of the nodes to
visit next.
1. Initialization:
o Start with a stack containing the initial node.
o Use a set to keep track of visited nodes to avoid processing the same node multiple times.
2. Traversal Process:
o Pop a node from the stack.
o If the node has not been visited, mark it as visited and process it (e.g., print it or add it to
a result list).
o Push all unvisited adjacent nodes of the current node onto the stack.
3. Termination:
o The traversal continues until the stack is empty, meaning all reachable nodes have been
processed.
Breadth-First Search (BFS) is a graph traversal method that explores all neighbor nodes at the present
depth level before moving on to nodes at the next depth level. It can be implemented using a queue,
which helps in processing nodes in a first-in-first-out (FIFO) manner.
1. Initialization:
o Start with a queue containing the initial node.
o Use a set to keep track of visited nodes to avoid processing the same node multiple times.
2. Traversal Process:
30
o Dequeue a node from the queue.
o If the node has not been visited, mark it as visited and process it (e.g., print it or add it to
a result list).
o Enqueue all unvisited adjacent nodes of the current node.
3. Termination:
o The traversal continues until the queue is empty, meaning all reachable nodes have been
processed
SAMPLE CODES
DFS Implementation
Write the program of DFS traversal of a directed graph using adjacency matrix for graph
representation and linked list representation for the traversal code. Provide its iterative and
recursive code.
#include <iostream>
using namespace std;
#define MAX 20
void create_graph();
void display();
void dfs_rec(int v);
void dfs(int v);
void bfs(int v);
void adj_nodes(int v);
void components();
int adj[MAX][MAX];
bool visited[MAX];
int n; // denotes number of nodes in the graph
int main() {
int i, v, choice;
create_graph();
while (1)
{
cout << "\n1.Adjacency matrix\n";
cout << "2.Depth First Search using stack\n";
cout << "3.Depth First Search through recursion\n";
cout << "4.Adjacent vertices\n";
cout << "5.Components\n";
cout << "6.Exit\n";
cout << "\nEnter your choice: ";
cin >> choice;
31
switch (choice)
{
case 1:
cout << "\nAdjacency Matric\n";
display();
break;
case 2:
cout << "\nEnter starting node Depth First Search: ";
cin >> v;
for (i = 1; i <= n; i++)
visited[i] = false;
dfs(v);
break;
case 3:
cout << "\nEnter starting node for Depth First Search: ";
cin >> v;
for(i = 1; i <= n; i++)
visited[i] = false;
dfs_rec(v);
break;
case 4:
cout << "\nEnter node to find adjacent vertices: ";
cin >> v;
cout << "\nAdjacent Vertices are: ";
adj_nodes(v);
break;
case 5:
components();
break;
case 6:
exit(1);
default:
cout << "\nWrong choice\n";
break;
}
}
}
void create_graph() {
int i, max_edges, origin, destin;
max_edges = n * (n-1);
32
cin >> destin;
else {
adj[origin][destin] = 1;
}
}
}
void display() {
int i, j;
void dfs_rec(int v) {
int i;
visited[v] = true;
cout << v;
void dfs(int v) {
int i, stack[MAX], top = -1, pop_v, j, t;
int ch;
top++;
stack[top] = v;
if(visited[pop_v] == false) {
cout << pop_v << " ";
33
visited[pop_v] = true;
}
else
continue;
void adj_nodes(int v) {
int i;
if(adj[v][i] == 1)
cout << i << " ";
cout << endl;
}
}
void components() {
int i;
Write a function to count the number of connected components in an undirected graph using DFS.
The graph is represented using an adjacency matrix.
#include <iostream>
using namespace std;
34
#define MAX 20
void create_graph();
void display();
void dfs_rec(int v);
void dfs(int v);
void bfs(int v);
void adj_nodes(int v);
void components();
int count_components();
int adj[MAX][MAX];
bool visited[MAX];
int n; // denotes number of nodes in the graph
int main() {
int i, v, choice;
create_graph();
while (1) {
cout << "\n1. Adjacency matrix\n";
cout << "2. Depth First Search using stack\n";
cout << "3. Depth First Search through recursion\n";
cout << "4. Adjacent vertices\n";
cout << "5. Components\n";
cout << "6. Count Connected Components\n";
cout << "7. Exit\n";
cout << "\nEnter your choice: ";
cin >> choice;
switch (choice) {
case 1:
cout << "\nAdjacency Matrix\n";
display();
break;
case 2:
cout << "\nEnter starting node for Depth First Search: ";
cin >> v;
for (i = 1; i <= n; i++)
visited[i] = false;
dfs(v);
cout << endl;
break;
case 3:
cout << "\nEnter starting node for Depth First Search: ";
cin >> v;
for (i = 1; i <= n; i++)
visited[i] = false;
dfs_rec(v);
cout << endl;
break;
35
case 4:
cout << "\nEnter node to find adjacent vertices: ";
cin >> v;
cout << "\nAdjacent Vertices are: ";
adj_nodes(v);
cout << endl;
break;
case 5:
components();
break;
case 6:
cout << "Number of connected components: " << count_components() << endl;
break;
case 7:
exit(1);
default:
cout << "\nWrong choice\n";
break;
}
}
}
void create_graph() {
int i, max_edges, origin, destin;
max_edges = n * (n - 1);
void display() {
36
int i, j;
void dfs_rec(int v) {
int i;
visited[v] = true;
cout << v << " ";
void dfs(int v) {
int i, stack[MAX], top = -1, pop_v;
top++;
stack[top] = v;
if (!visited[pop_v]) {
cout << pop_v << " ";
visited[pop_v] = true;
} else {
continue;
}
void adj_nodes(int v) {
int i;
37
cout << i << " ";
}
cout << endl;
}
void components() {
int i;
int count_components() {
int i, count = 0;
BFS Implementation
Write the program of BFS traversal of a directed graph using adjacency matrix for graph
representation and linked list representation for the traversal code.
#include <iostream>
using namespace std;
#define MAX 20
void create_graph();
void display();
void dfs_rec(int v);
38
void dfs(int v);
void bfs(int v);
void adj_nodes(int v);
void components();
int adj[MAX][MAX];
bool visited[MAX];
int n; // denotes number of nodes in the graph
int main() {
int i, v, choice;
create_graph();
while (1)
{
cout << "\n1.Adjacency matrix\n";
cout << "2.Depth First Search using stack\n";
cout << "3.Depth First Search through recursion\n";
cout << "4.Breadth First Search\n";
cout << "5.Adjacent vertices\n";
cout << "6.Components\n";
cout << "7.Exit\n";
cout << "\nEnter your choice: ";
cin >> choice;
switch (choice)
{
case 1:
cout << "\nAdjacency Matric\n";
display();
break;
case 2:
cout << "\nEnter starting node Depth First Search: ";
cin >> v;
for (i = 1; i <= n; i++)
visited[i] = false;
dfs(v);
break;
case 3:
cout << "\nEnter starting node for Depth First Search: ";
cin >> v;
for(i = 1; i <= n; i++)
visited[i] = false;
dfs_rec(v);
break;
case 4:
cout << "\nEnter starting node for Breadth First Search: ";
cin >> v;
for(i = 1; i <= n; i++)
visited[i] = false;
bfs(v);
39
break;
case 5:
cout << "\nEnter node to find adjacent vertices: ";
cin >> v;
cout << "\nAdjacent Vertices are: ";
adj_nodes(v);
break;
case 6:
components();
break;
case 7:
exit(1);
default:
cout << "\nWrong choice\n";
break;
}
}
}
void create_graph() {
int i, max_edges, origin, destin;
max_edges = n * (n-1);
else {
adj[origin][destin] = 1;
}
}
}
void display() {
int i, j;
40
for(i = 1; i <= n; i++) {
void dfs_rec(int v) {
int i;
visited[v] = true;
cout << v;
void dfs(int v) {
int i, stack[MAX], top = -1, pop_v, j, t;
int ch;
top++;
stack[top] = v;
if(visited[pop_v] == false) {
cout << pop_v << " ";
visited[pop_v] = true;
}
else
continue;
void bfs(int v) {
int i, front, rear;
int que[20];
41
front = rear = -1;
cout << v;
visited[v] = true;
rear++;
front++;
que[rear] = v;
void adj_nodes(int v) {
int i;
if(adj[v][i] == 1)
cout << i << " ";
cout << endl;
}
}
void components() {
int i;
42
}
Write a C++ program to find if there is a path between two vertices in a directed graph
using BFS algorithm.
#include <iostream>
using namespace std;
#define MAX 20
void create_graph();
void display();
void dfs_rec(int v);
void dfs(int v);
void bfs(int v);
void adj_nodes(int v);
void components();
bool is_path_bfs(int start, int end);
int adj[MAX][MAX];
bool visited[MAX];
int n; // denotes number of nodes in the graph
int main() {
int i, v, choice;
create_graph();
while (1) {
cout << "\n1. Adjacency matrix\n";
cout << "2. Breadth First Search\n";
cout << "3. Adjacent vertices\n";
cout << "4. Components\n";
cout << "5. Find path between two vertices\n";
cout << "6. Exit\n";
cout << "\nEnter your choice: ";
cin >> choice;
switch (choice) {
case 1:
cout << "\nAdjacency Matrix\n";
display();
break;
case 2:
cout << "\nEnter starting node for Breadth First Search: ";
cin >> v;
for (i = 1; i <= n; i++)
43
visited[i] = false;
bfs(v);
break;
case 3:
cout << "\nEnter node to find adjacent vertices: ";
cin >> v;
cout << "\nAdjacent Vertices are: ";
adj_nodes(v);
break;
case 4:
components();
break;
case 5: {
int start, end;
cout << "\nEnter start node: ";
cin >> start;
cout << "Enter end node: ";
cin >> end;
if (is_path_bfs(start, end))
cout << "\nThere is a path from " << start << " to " << end << "\n";
else
cout << "\nNo path exists from " << start << " to " << end << "\n";
break;
}
case 6:
exit(1);
default:
cout << "\nWrong choice\n";
break;
}
}
}
void create_graph() {
int i, max_edges, origin, destin;
max_edges = n * (n - 1);
44
cout << "\nInvalid edge!\n";
i--;
} else {
adj[origin][destin] = 1;
}
}
}
void display() {
int i, j;
void bfs(int v) {
int i, front, rear;
int que[MAX];
front = rear = -1;
visited[v] = true;
rear++;
front++;
que[rear] = v;
void adj_nodes(int v) {
int i;
45
if (adj[v][i] == 1)
cout << i << " ";
}
cout << endl;
}
void components() {
int i;
void dfs_rec(int v) {
int i;
visited[v] = true;
cout << v << " ";
void dfs(int v) {
int i;
visited[v] = true;
cout << v << " ";
46
visited[start] = true;
rear++;
front++;
que[rear] = start;
return false;
}
47