Fix Non Recursive Depth First Search (#2207)

* Fix Non Recursive Depth First Search

* Unindent docstring

* Reindent docstring by 1 space

Co-authored-by: Christian Clauss <cclauss@me.com>

Co-authored-by: Christian Clauss <cclauss@me.com>
This commit is contained in:
Marcos Cannabrava 2020-09-11 11:23:26 -03:00 committed by GitHub
parent 1b3fec3f1f
commit a191f89fe2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,24 +1,12 @@
"""The DFS function simply calls itself recursively for every unvisited child of """Non recursive implementation of a DFS algorithm."""
its argument. We can emulate that behaviour precisely using a stack of iterators.
Instead of recursively calling with a node, we'll push an iterator to the node's
children onto the iterator stack. When the iterator at the top of the stack
terminates, we'll pop it off the stack.
Pseudocode: from typing import Set, Dict
all nodes initially unexplored
mark s as explored
for every edge (s, v):
if v unexplored:
DFS(G, v)
"""
from typing import Dict, Set
def depth_first_search(graph: Dict, start: str) -> Set[int]: def depth_first_search(graph: Dict, start: str) -> Set[int]:
"""Depth First Search on Graph """Depth First Search on Graph
:param graph: directed graph in dictionary format :param graph: directed graph in dictionary format
:param vertex: starting vectex as a string :param vertex: starting vertex as a string
:returns: the trace of the search :returns: the trace of the search
>>> G = { "A": ["B", "C", "D"], "B": ["A", "D", "E"], >>> G = { "A": ["B", "C", "D"], "B": ["A", "D", "E"],
... "C": ["A", "F"], "D": ["B", "D"], "E": ["B", "F"], ... "C": ["A", "F"], "D": ["B", "D"], "E": ["B", "F"],
@ -31,13 +19,16 @@ def depth_first_search(graph: Dict, start: str) -> Set[int]:
True True
""" """
explored, stack = set(start), [start] explored, stack = set(start), [start]
while stack: while stack:
v = stack.pop() v = stack.pop()
# one difference from BFS is to pop last element here instead of first one explored.add(v)
for w in graph[v]: # Differences from BFS:
if w not in explored: # 1) pop last element instead of first one
explored.add(w) # 2) add adjacent elements to stack without exploring them
stack.append(w) for adj in reversed(graph[v]):
if adj not in explored:
stack.append(adj)
return explored return explored