Initialize set with source in DFS (#1872)

* Update dfs.py

* Add type hints, rearrange doc-strings and comments

* fixup! Format Python code with psf/black push

* dfs -> depth_first_search

Co-Authored-By: Christian Clauss <cclauss@me.com>

* dfs -> depth_first_search

* Add doctest for DFS

* fixup! Format Python code with psf/black push

* Rename dfs.py to depth_first_search_dictionary.py

* updating DIRECTORY.md

* Rename depth_first_search_dictionary.py to depth_first_search_dfs.py

* updating DIRECTORY.md

* Rename depth_first_search.py to depth_first_search_2.py

* updating DIRECTORY.md

* Rename depth_first_search_dfs.py to depth_first_search.py

* updating DIRECTORY.md

Co-authored-by: John Law <johnlaw.po@gmail.com>
Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
This commit is contained in:
Sanders Lin 2020-04-18 02:05:29 +08:00 committed by GitHub
parent 1c9d4a3929
commit 7aaf79cc23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 116 additions and 101 deletions

View File

@ -212,7 +212,7 @@
* [Check Bipartite Graph Bfs](https://github.com/TheAlgorithms/Python/blob/master/graphs/check_bipartite_graph_bfs.py)
* [Check Bipartite Graph Dfs](https://github.com/TheAlgorithms/Python/blob/master/graphs/check_bipartite_graph_dfs.py)
* [Depth First Search](https://github.com/TheAlgorithms/Python/blob/master/graphs/depth_first_search.py)
* [Dfs](https://github.com/TheAlgorithms/Python/blob/master/graphs/dfs.py)
* [Depth First Search 2](https://github.com/TheAlgorithms/Python/blob/master/graphs/depth_first_search_2.py)
* [Dijkstra](https://github.com/TheAlgorithms/Python/blob/master/graphs/dijkstra.py)
* [Dijkstra 2](https://github.com/TheAlgorithms/Python/blob/master/graphs/dijkstra_2.py)
* [Dijkstra Algorithm](https://github.com/TheAlgorithms/Python/blob/master/graphs/dijkstra_algorithm.py)

View File

@ -1,65 +1,59 @@
#!/usr/bin/python
"""The DFS function simply calls itself recursively for every unvisited child of
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.
""" Author: OMKAR PATHAK """
Pseudocode:
all nodes initially unexplored
mark s as explored
for every edge (s, v):
if v unexplored:
DFS(G, v)
"""
from typing import Set, Dict
class Graph:
def __init__(self):
self.vertex = {}
def depth_first_search(graph: Dict, start: str) -> Set[int]:
"""Depth First Search on Graph
# for printing the Graph vertices
def printGraph(self):
print(self.vertex)
for i in self.vertex.keys():
print(i, " -> ", " -> ".join([str(j) for j in self.vertex[i]]))
:param graph: directed graph in dictionary format
:param vertex: starting vectex as a string
:returns: the trace of the search
>>> G = { "A": ["B", "C", "D"], "B": ["A", "D", "E"],
... "C": ["A", "F"], "D": ["B", "D"], "E": ["B", "F"],
... "F": ["C", "E", "G"], "G": ["F"] }
>>> start = "A"
>>> output_G = list({'A', 'B', 'C', 'D', 'E', 'F', 'G'})
>>> all(x in output_G for x in list(depth_first_search(G, "A")))
True
>>> all(x in output_G for x in list(depth_first_search(G, "G")))
True
"""
explored, stack = set(start), [start]
while stack:
v = stack.pop()
# one difference from BFS is to pop last element here instead of first one
for w in graph[v]:
if w not in explored:
explored.add(w)
stack.append(w)
return explored
# for adding the edge between two vertices
def addEdge(self, fromVertex, toVertex):
# check if vertex is already present,
if fromVertex in self.vertex.keys():
self.vertex[fromVertex].append(toVertex)
else:
# else make a new vertex
self.vertex[fromVertex] = [toVertex]
def DFS(self):
# visited array for storing already visited nodes
visited = [False] * len(self.vertex)
# call the recursive helper function
for i in range(len(self.vertex)):
if visited[i] == False:
self.DFSRec(i, visited)
def DFSRec(self, startVertex, visited):
# mark start vertex as visited
visited[startVertex] = True
print(startVertex, end=" ")
# Recur for all the vertices that are adjacent to this node
for i in self.vertex.keys():
if visited[i] == False:
self.DFSRec(i, visited)
G = {
"A": ["B", "C", "D"],
"B": ["A", "D", "E"],
"C": ["A", "F"],
"D": ["B", "D"],
"E": ["B", "F"],
"F": ["C", "E", "G"],
"G": ["F"],
}
if __name__ == "__main__":
g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)
import doctest
g.printGraph()
print("DFS:")
g.DFS()
# OUTPUT:
# 0  ->  1 -> 2
# 1  ->  2
# 2  ->  0 -> 3
# 3  ->  3
# DFS:
#  0 1 2 3
doctest.testmod()
print(depth_first_search(G, "A"))

View File

@ -0,0 +1,65 @@
#!/usr/bin/python
""" Author: OMKAR PATHAK """
class Graph:
def __init__(self):
self.vertex = {}
# for printing the Graph vertices
def printGraph(self):
print(self.vertex)
for i in self.vertex.keys():
print(i, " -> ", " -> ".join([str(j) for j in self.vertex[i]]))
# for adding the edge between two vertices
def addEdge(self, fromVertex, toVertex):
# check if vertex is already present,
if fromVertex in self.vertex.keys():
self.vertex[fromVertex].append(toVertex)
else:
# else make a new vertex
self.vertex[fromVertex] = [toVertex]
def DFS(self):
# visited array for storing already visited nodes
visited = [False] * len(self.vertex)
# call the recursive helper function
for i in range(len(self.vertex)):
if visited[i] == False:
self.DFSRec(i, visited)
def DFSRec(self, startVertex, visited):
# mark start vertex as visited
visited[startVertex] = True
print(startVertex, end=" ")
# Recur for all the vertices that are adjacent to this node
for i in self.vertex.keys():
if visited[i] == False:
self.DFSRec(i, visited)
if __name__ == "__main__":
g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)
g.printGraph()
print("DFS:")
g.DFS()
# OUTPUT:
# 0  ->  1 -> 2
# 1  ->  2
# 2  ->  0 -> 3
# 3  ->  3
# DFS:
#  0 1 2 3

View File

@ -1,44 +0,0 @@
"""pseudo-code"""
"""
DFS(graph G, start vertex s):
// all nodes initially unexplored
mark s as explored
for every edge (s, v):
if v unexplored:
DFS(G, v)
"""
def dfs(graph, start):
"""The DFS function simply calls itself recursively for every unvisited child of 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."""
explored, stack = set(), [start]
while stack:
v = (
stack.pop()
) # one difference from BFS is to pop last element here instead of first one
if v in explored:
continue
explored.add(v)
for w in graph[v]:
if w not in explored:
stack.append(w)
return explored
G = {
"A": ["B", "C"],
"B": ["A", "D", "E"],
"C": ["A", "F"],
"D": ["B"],
"E": ["B", "F"],
"F": ["C", "E"],
}
print(dfs(G, "A"))