def dfs(graph, node):
"""Run DFS through the graph from the starting
node and return the nodes in order of finishing time.
"""
stack = [[node, True]]
while True in [x[1] for x in stack]:
i = 0
for x in xrange(len(stack)):
if stack[x][1] == True:
i = x
break
stack[i][1] = False
stack = [[x, True] for x in graph[stack[i][0]] \
if (([x, True] not in stack) and ([x, False] not in stack))] + stack
return [x[0] for x in stack]
Input: Graph as adjacency list Eg: {1:[2, 3], 2:[1], 3:[]}
Node is an integer value from where depth first search begins Eg: 1
Output: The list of nodes in order of their finishing times.
Eg: [3, 2, 1]
For large graphs, the above code is taking too long to execute. Is there a better way to do this?
Edit: I could do better time by implementing the following code. Is it possible to do even better?
def dfs(graph, node):
"""Run DFS through the graph from the starting
node and return the nodes in order of finishing time.
"""
seen = defaultdict(bool)
stack = [node]
while True:
flag = True
for x in stack:
if not seen[x]:
stack = [a for a in graph[x] if not seen[a]] + stack
seen[x] = True
flag = False
break
if flag:
break
return stack
Edit: I've changed seen and stack variables to sets. But I'm not getting the required performance boost. What am I doing wrong?
def dfs(graph, node):
"""Run DFS through the graph from the starting
node and return the nodes in order of finishing time.
"""
seen = set()
stack = {node}
while True:
flag = True
for x in stack:
if x not in seen:
stack = stack.union(set(graph[x]))
seen = seen.union({x})
flag = False
break
if flag:
break
return list(stack)