Can you please let me know what is incorrect in below DFS code. It's giving correct result AFAIK, but I don't know when it will fail.
graph1 = {
'A' : ['B','S'],
'B' : ['A'],
'C' : ['D','E','F','S'],
'D' : ['C'],
'E' : ['C','H'],
'F' : ['C','G'],
'G' : ['F','S'],
'H' : ['E','G'],
'S' : ['A','C','G']
}
visited = []
def dfs(graph,node):
global visited
if node not in visited:
visited.append(node)
for n in graph[node]:
dfs(graph,n)
dfs(graph1,'A')
print(visited)
Output:
['A', 'B', 'S', 'C', 'D', 'E', 'H', 'G', 'F']
10 Answers 10
I think you have an indentation problem there. Assuming your code looks like this:
graph1 = {
'A' : ['B','S'],
'B' : ['A'],
'C' : ['D','E','F','S'],
'D' : ['C'],
'E' : ['C','H'],
'F' : ['C','G'],
'G' : ['F','S'],
'H' : ['E','G'],
'S' : ['A','C','G']
}
visited = []
def dfs(graph,node):
global visited
if node not in visited:
visited.append(node)
for n in graph[node]:
dfs(graph,n)
dfs(graph1,'A')
print(visited)
I would say a couple of things:
- Avoid globals if you can
- Instead of a list for visited, use a set
plus:
- This will not work for forests but I assume you already know that
- It will fail if you reference a node that does not exist.
Updated code:
graph1 = {
'A' : ['B','S'],
'B' : ['A'],
'C' : ['D','E','F','S'],
'D' : ['C'],
'E' : ['C','H'],
'F' : ['C','G'],
'G' : ['F','S'],
'H' : ['E','G'],
'S' : ['A','C','G']
}
def dfs(graph, node, visited):
if node not in visited:
visited.append(node)
for n in graph[node]:
dfs(graph,n, visited)
return visited
visited = dfs(graph1,'A', [])
print(visited)
5 Comments
visited
as dict
or list
?visited.append(node)
the variable visited is a list.visited
should be a set to reduce runtime by o(n)Without recursion:
def dfs(graph, node):
visited = set((node,))
output = [node]
stack = [node]
while stack:
node = stack[-1]
if node not in visited:
output.append(node)
visited.add(node)
remove_from_stack = True
for next_node in graph[node]:
if next_node not in visited:
stack.append(next_node)
remove_from_stack = False
break
if remove_from_stack:
stack.pop()
return output
print (dfs(graph1, 'A'))
Output:
['A', 'B', 'S', 'C', 'D', 'E', 'H', 'G', 'F']
5 Comments
extend
instead of append
? 2. Why is visited
a list and not a set?append
is fine. I prefer to leave visited
as it is so it can keeps track of the visit ordero(n)
in performance.next
is a reserved word in PythonHere's an iterative (non-recursive) implementation of a DFS:
def dfs_iterative(graph, start_vertex):
visited = set()
traversal = []
stack = [start_vertex]
while len(stack) > 0:
vertex = stack.pop()
if vertex not in visited:
visited.add(vertex)
traversal.append(vertex)
stack.extend(reversed(graph[vertex])) # add vertex in the same order as visited
return traversal
test_graph = {
'A' : ['B','S'],
'B' : ['A'],
'C' : ['D','E','F','S'],
'D' : ['C'],
'E' : ['C','H'],
'F' : ['C','G'],
'G' : ['F','S'],
'H' : ['E','G'],
'S' : ['A','C','G']
}
print(dfs_iterative(test_graph, 'A'))
Output:
['A', 'B', 'S', 'C', 'D', 'E', 'H', 'G', 'F']
Comments
from collections import defaultdict
class Graph:
def __init__(self):
self.graph = defaultdict(list)
def addEdge(self,u,v):
self.graph[u].append(v)
def DFS(self,v,vertex):
visited = [False]*vertex
print(self. graph)
# print(len(self.graph),"+++")
self.DFSUtil(v,visited)
def DFSUtil(self,v,visited):
visited[v]=True
print(v)
for i in self.graph[v]:
if visited[i] == False:
# print(visited)
self.DFSUtil(i,visited)
g= Graph()
vertex=7
g.addEdge(0,1)
g.addEdge(0,2)
g.addEdge(0,6)
g.addEdge(0,5)
g.addEdge(5,3)
g.addEdge(5,4)
g.addEdge(4,3)
g.addEdge(6,4)
g.DFS(0,vertex)
This is the modification for the above code because that doesn't work with in all cases.
We have to specify the number of vectors and then give edges manually.
1 Comment
graph = {'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']}
def dfs(s,d):
def dfs_helper(s,d):
if s == d:
return True
if s in visited :
return False
visited.add(s)
for c in graph[s]:
dfs_helper(c,d)
return False
visited = set()
return dfs_helper(s,d)
dfs('A','E') ---- True
dfs('A','M') ---- False
Comments
DFS implementation in Python
from collections import defaultdict
class Graph:
def __init__(self):
self.graph = defaultdict(list)
def addEdge(self, u, v):
self.graph[u].append(v)
def DFSUtil(self, v, visited):
visited[v]=True
print(v)
for i in self.graph[v]:
if visited[i] == False:
self.DFSUtil(i, visited)
def DFS(self):
V = len(self.graph)
visited = [False]*(V)
for i in range(V):
if visited[i] == False:
self.DFSUtil(i, visited)
# Driver code
# Create a graph given in the above diagram
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)
print("Following is Depth First Traversal")
g.DFS()
Source :: this
1 Comment
Here is a more versatile algorithm, the one asked in the question works only for undirected graphs. But this hopefully works for both them. Check it out
graph1= {
'A' : ['B','S'],
'B' : [],
'C' : ['E','S'],
'D' : ['C'],
'E' : ['H'],
'F' : ['C'],
'G' : ['F','S'],
'H' : ['G'],
'S' : []
}
visited = []
def dfs_visit(graph, s):
global visited
for v in graph[s]:
if v not in visited:
visited.append(v)
dfs_visit(graph, v)
def dfs(graph):
global visited
for v in [*graph]:
if v not in visited:
visited.append(v)
dfs_visit(graph,v)
dfs(graph1)
print(visited)
Comments
def DFS(graph,pointer,visit):
visit.add(pointer)
print(pointer,end=' ')
for travel in graph[pointer]-visit:
if travel not in visit:
DFS(graph,travel,visit)
graph={'0':set(['1','2','3']),'1':set(['0','2']),'2':set(['0','1','4']),'3':set(['0']),'4':set(['2'])}
visit=set()
print("DFS for graph: ",graph)
DFS(graph,'0',visit)
Output
DFS for graph: {'0': {'1', '3', '2'}, '1': {'0', '2'}, '2': {'1', '0', '4'}, '3': {'0'}, '4': {'2'}}
0 1 2 4 3
Comments
A recursive implementation:
def dfs(G, u, visited=[]):
"""Recursion version for depth-first search (DFS).
Args:
G: a graph
u: start
visited: a list containing all visited nodes in G
Return:
visited
"""
visited.append(u)
for v in G[u]:
if v not in visited:
dfs(G, v, visited)
return visited
An iterative implementation using a stack:
def dfs_iterative(G, u, visited=[]):
stack = [u, ] #initialize
while stack:
u = stack.pop()
if u not in visited:
visited.append(u)
stack.extend(reversed(G[u])) #reversed() is used as the same traversal as recursive DFS
return visited
Comments
very basic code ig
def dfs(arr,vertex):
dfs=[]
stack=[]
stack.append(vertex)
while len(stack)!=0:
top=stack.pop()
if top not in dfs:
dfs.append(top)
for i in arr[top]:
if i in dfs:
continue
stack.append(top)
stack.append(i)
break
return dfs
print(dfs(arr,'A'))
global
s avoid them as much as possible!!