You are on page 1of 4

No of the Experiment: 02

Name of the Experiment: Implementation of BFS and DFS in Python without Using Any
Library Function

Objectives:
• To understand the basics of DFS and BFS
• To differentiate between DFS and BFS
• To implement the DFS and BFS in real life problem solving

Theory:
BFS (Breadth-First Search):
BFS, or breadth-first search, is a method of visiting every node in a graph sequentially. To put it
another way, it investigates every node's neighbor before going on to the neighbors of its neighbors.
Before moving on to the nodes at the next level, it visits every node at the same level beginning
with the root node. A queue data structure can be used to implement BFS.
DFS (Depth-First Search):
Depth-First Search, or DFS, is a method for visiting each node in a graph one at a time. In other
words, it follows each branch as far as it can go before turning around. Before turning around, it
begins at the root node and travels as far as it can along each branch. Recursion or a stack data
structure can be used to implement DFS.
Main differences between BFS and DFS:
The main differences between BFS and DFS are as follows:
• Approach: BFS traverses the graph level by level, visiting all the nodes at a given level
before moving to the next level. DFS, on the other hand, explores the graph by visiting a
node and then recursively exploring all the nodes that can be reached from that node.
• Data structure used: BFS uses a queue data structure to keep track of the nodes to be visited,
while DFS uses a stack or recursion to keep track of the nodes.
• Memory usage: BFS tends to use more memory as it keeps all the nodes at a given level in
memory before moving to the next level. DFS uses less memory as it only keeps the current
path in memory.
• Completeness: BFS is guaranteed to find the shortest path between two nodes if one exists,
whereas DFS may find a longer path before finding the shortest path.
• Time complexity: Both algorithms have a time complexity of O(V+E), where V is the
number of vertices and E is the number of edges in the graph. However, the actual running
time can vary depending on the structure of the graph and the chosen implementation.
In summary, BFS is a good choice when we need to find the shortest path between two nodes,
while DFS is useful when we want to visit all the nodes in a graph or find a path between two
nodes without necessarily finding the shortest one.
Problem Statement:
We must go from 0 to 4, where 0 have two following branches: 1 and 2, 1 will have one branch
named 3 and 2 will have one branch named 4. We have to use BFS and DFS to select the path from
0 to 4.

Code:
# Define a Graph class to represent the graph
class Graph:
def __init__(self, vertices):
self.vertices = vertices
self.adj_matrix = [[0 for x in range(vertices)] for y in range(vertices)]
def add_edge(self, v1, v2):
self.adj_matrix[v1][v2] = 1
self.adj_matrix[v2][v1] = 1
def bfs(self, start, end):
visited = [False] * self.vertices
queue = []
path = []
queue.append(start)
visited[start] = True
while queue:
node = queue.pop(0)
path.append(node)
if node == end:
return path
for neighbor in range(self.vertices):
if self.adj_matrix[node][neighbor] == 1 and not visited[neighbor]:
queue.append(neighbor)
visited[neighbor] = True
return None
def dfs(self, start, end, visited=None, path=None):
if visited is None:
visited = [False] * self.vertices
if path is None:
path = []
visited[start] = True
path.append(start)
if start == end:
return path
for neighbor in range(self.vertices):
if self.adj_matrix[start][neighbor] == 1 and not visited[neighbor]:
dfs_path = self.dfs(neighbor, end, visited, path)
if dfs_path is not None:
return dfs_path
path.pop()
visited[start] = False
return None
# Example usage:
g = Graph(5)
g.add_edge(0, 1)
g.add_edge(0, 2)
g.add_edge(1, 3)
g.add_edge(2, 4)
print(g.bfs(0, 4))
print(g.dfs(0, 4))

Output:
[0, 1, 2, 3, 4]
[0, 2, 4]
Discussion:
In this example, a ‘Graph’ class was created that represented the graph using an adjacency matrix.
Both BFS and DFS were defined. The BFS method used a queue to keep track of nodes to visit,
while the DFS method used recursion. To use these algorithms, a graph was created and added
edges to it using the ‘add_edge’ method, either the ‘bfs’ or ‘dfs’ method was called with the starting
and ending nodes as parameters. The method returned the path from the starting node to the ending
node. Thus, the output of the problem was found.

Conclusion:
The result of the program correctly justified the working process of BFS and DFS as, in BFS, it
investigates every node's neighbor before going on to the neighbors of its neighbors so the result
was found as [0, 1, 2, 3, 4], on the other hand, in DFS, it follows each branch as far as it can go
before turning around, so the result was found as [0, 2, 4]. So, the code was justified.

You might also like