Skip to content

Commit 17bbd62

Browse files
Merge pull request #177 from jerryderry/bfs-dfs-python
bfs and dfs of graphs in python
2 parents bc9abec + 34805da commit 17bbd62

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

python/31_bfs_dfs/bfs_dfs.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
"""
2+
Breadth-first search and depth-first search.
3+
4+
Author: Wenru Dong
5+
"""
6+
7+
from typing import List, Optional, Generator, IO
8+
from collections import deque
9+
10+
class Graph:
11+
"""Undirected graph."""
12+
def __init__(self, num_vertices: int):
13+
self._num_vertices = num_vertices
14+
self._adjacency = [[] for _ in range(num_vertices)]
15+
16+
def add_edge(self, s: int, t: int) -> None:
17+
self._adjacency[s].append(t)
18+
self._adjacency[t].append(s)
19+
20+
def _generate_path(self, s: int, t: int, prev: List[Optional[int]]) -> Generator[str, None, None]:
21+
if prev[t] or s != t:
22+
yield from self._generate_path(s, prev[t], prev)
23+
yield str(t)
24+
25+
def bfs(self, s: int, t: int) -> IO[str]:
26+
"""Print out the path from Vertex s to Vertex t
27+
using bfs.
28+
"""
29+
if s == t: return
30+
31+
visited = [False] * self._num_vertices
32+
visited[s] = True
33+
q = deque()
34+
q.append(s)
35+
prev = [None] * self._num_vertices
36+
37+
while q:
38+
v = q.popleft()
39+
for neighbour in self._adjacency[v]:
40+
if not visited[neighbour]:
41+
prev[neighbour] = v
42+
if neighbour == t:
43+
print("->".join(self._generate_path(s, t, prev)))
44+
return
45+
visited[neighbour] = True
46+
q.append(neighbour)
47+
48+
def dfs(self, s: int, t: int) -> IO[str]:
49+
"""Print out a path from Vertex s to Vertex t
50+
using dfs.
51+
"""
52+
found = False
53+
visited = [False] * self._num_vertices
54+
prev = [None] * self._num_vertices
55+
56+
def _dfs(from_vertex: int) -> None:
57+
nonlocal found
58+
if found: return
59+
visited[from_vertex] = True
60+
if from_vertex == t:
61+
found = True
62+
return
63+
for neighbour in self._adjacency[from_vertex]:
64+
if not visited[neighbour]:
65+
prev[neighbour] = from_vertex
66+
_dfs(neighbour)
67+
68+
_dfs(s)
69+
print("->".join(self._generate_path(s, t, prev)))
70+
71+
72+
if __name__ == "__main__":
73+
74+
graph = Graph(8)
75+
76+
graph.add_edge(0, 1)
77+
graph.add_edge(0, 3)
78+
graph.add_edge(1, 2)
79+
graph.add_edge(1, 4)
80+
graph.add_edge(2, 5)
81+
graph.add_edge(3, 4)
82+
graph.add_edge(4, 5)
83+
graph.add_edge(4, 6)
84+
graph.add_edge(5, 7)
85+
graph.add_edge(6, 7)
86+
87+
graph.bfs(0, 7)
88+
graph.dfs(0, 7)

0 commit comments

Comments
 (0)