Skip to content

Commit 2b76ab3

Browse files
Fix Non Recursive Depth First Search
1 parent 1b3fec3 commit 2b76ab3

File tree

1 file changed

+23
-31
lines changed

1 file changed

+23
-31
lines changed

graphs/depth_first_search.py

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,35 @@
1-
"""The DFS function simply calls itself recursively for every unvisited child of
2-
its argument. We can emulate that behaviour precisely using a stack of iterators.
3-
Instead of recursively calling with a node, we'll push an iterator to the node's
4-
children onto the iterator stack. When the iterator at the top of the stack
5-
terminates, we'll pop it off the stack.
6-
7-
Pseudocode:
8-
all nodes initially unexplored
9-
mark s as explored
10-
for every edge (s, v):
11-
if v unexplored:
12-
DFS(G, v)
13-
"""
14-
from typing import Dict, Set
1+
"""Non recursive implementation of a DFS algorithm."""
2+
3+
from typing import Set, Dict
154

165

176
def depth_first_search(graph: Dict, start: str) -> Set[int]:
187
"""Depth First Search on Graph
198
20-
:param graph: directed graph in dictionary format
21-
:param vertex: starting vectex as a string
22-
:returns: the trace of the search
23-
>>> G = { "A": ["B", "C", "D"], "B": ["A", "D", "E"],
24-
... "C": ["A", "F"], "D": ["B", "D"], "E": ["B", "F"],
25-
... "F": ["C", "E", "G"], "G": ["F"] }
26-
>>> start = "A"
27-
>>> output_G = list({'A', 'B', 'C', 'D', 'E', 'F', 'G'})
28-
>>> all(x in output_G for x in list(depth_first_search(G, "A")))
29-
True
30-
>>> all(x in output_G for x in list(depth_first_search(G, "G")))
31-
True
9+
:param graph: directed graph in dictionary format
10+
:param vertex: starting vertex as a string
11+
:returns: the trace of the search
12+
>>> G = { "A": ["B", "C", "D"], "B": ["A", "D", "E"],
13+
... "C": ["A", "F"], "D": ["B", "D"], "E": ["B", "F"],
14+
... "F": ["C", "E", "G"], "G": ["F"] }
15+
>>> start = "A"
16+
>>> output_G = list({'A', 'B', 'C', 'D', 'E', 'F', 'G'})
17+
>>> all(x in output_G for x in list(depth_first_search(G, "A")))
18+
True
19+
>>> all(x in output_G for x in list(depth_first_search(G, "G")))
20+
True
3221
"""
3322
explored, stack = set(start), [start]
23+
3424
while stack:
3525
v = stack.pop()
36-
# one difference from BFS is to pop last element here instead of first one
37-
for w in graph[v]:
38-
if w not in explored:
39-
explored.add(w)
40-
stack.append(w)
26+
explored.add(v)
27+
# Differences from BFS:
28+
# 1) pop last element instead of first one
29+
# 2) add adjacent elements to stack without exploring them
30+
for adj in reversed(graph[v]):
31+
if adj not in explored:
32+
stack.append(adj)
4133
return explored
4234

4335

0 commit comments

Comments
 (0)