12

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']
Juan Leni
7,7088 gold badges62 silver badges90 bronze badges
asked Apr 15, 2017 at 19:23
7
  • 2
    First of all: don't use globals avoid them as much as possible!! Commented Apr 15, 2017 at 19:24
  • 2
    DFS is a search algorithm, but there is no target defined you are looking for... Commented Apr 15, 2017 at 19:28
  • Thanks for the response.. visited = [] def dfs(graph,node,visited): if node not in visited: visited.append(node) for n in graph[node]: dfs(graph,n,visited) dfs(graph1,'A',visited) print(visited) Commented Apr 15, 2017 at 19:29
  • I'm also not convinced that the output you show is generated by the data you show - I don't see where S, H and G come from? (But I could possibly be wrong here) Commented Apr 15, 2017 at 19:32
  • Hi Willem, if you checkout the link eddmann.com/posts/… there a sample code for the DFS is given but If I change the graph as given in youtube tutorial "youtu.be/iaBEKo5sM7w" I am not getting the result as mentioned. So I thought of writing my own version based on the tutorial. Commented Apr 15, 2017 at 19:34

10 Answers 10

21

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)
answered May 9, 2017 at 11:55

5 Comments

Should the updated code contain the variable visited as dict or list?
@Sudarshan since it says visited.append(node) the variable visited is a list.
@Juan Leni or anyone listening: In the for loop of your code, how is variable n not stuck in values between 'B' and 'A' and how come it jumps to 'S' in the third iteration?
visited should be a set to reduce runtime by o(n)
making visited a bit vector reduces checks to O(1), but one could instead store for every vertex the adjacent vertices in sets and remove visited vertices directly from them.
14

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']
Gulzar
28.6k42 gold badges158 silver badges257 bronze badges
answered Aug 15, 2018 at 20:24

5 Comments

1. Why 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 order
If it is a list, you lose o(n) in performance.
Also note that next is a reserved word in Python
agree, I added a variable output to keep the right visited order
6

Here'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']

Gulzar
28.6k42 gold badges158 silver badges257 bronze badges
answered Mar 15, 2020 at 22:38

Comments

1
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.

Yuca
6,1114 gold badges26 silver badges45 bronze badges
answered Oct 25, 2018 at 11:48

1 Comment

which cases does the above code fail for?
0
 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
answered Sep 11, 2018 at 19:28

Comments

0

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

answered Jan 12, 2018 at 5:01

1 Comment

@AssafLivne why not? Would you mind to expand a bit on that?
0

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)
answered Jul 2, 2020 at 13:51

Comments

0
 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 
answered Mar 23, 2021 at 6:13

Comments

0

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
answered Jul 6, 2021 at 9:51

Comments

-1

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'))
answered Nov 25, 2023 at 19:43

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.