nathanwailes

Depth-first search (iterative)

Mar 29th, 2024 (edited)
891
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.59 KB | None | 0 0
  1. """
  2. You'll see that the iterative version prints out 1-3-2-5-4, while the recursive version prints out 1-2-4-5-3.
  3. What determines the different order of the handling of the nodes between the iterative and recursive versions of this code
  4. is the fact that in the iterative version the 'for neighbor in graph' finishes adding all of the neighbors before the next
  5. neighbor is popped off the stack, so the later neighbors get recursed before the earlier neighbors, whereas in the recursive
  6. version the neighbors are recursed immediately as they're encountered within that for loop, so the earlier neighbors get
  7. recursed before the later neighbors.
  8. So, for example, if the graph says "1: [2, 3]", iterative DFS will have the 3 visited first, recursive DFS will have the 2 visited first.
  9.  
  10. Pseudocode:
  11. dfs_i: need graph and start_node
  12.    # create a 'visited' set and stack
  13.    # pop from the stack while you can
  14.    # process the vertex
  15.    # loop through the neighbors, appending each to the stack
  16.  
  17. Interesting discussions to have / think about:
  18. 1. Why are there two checks for if a vertex is in the visited set?
  19. - I think the first/outer one protects you if you have a node that's pointed to by two different nodes. For example, if you have a parent pointing to two nodes, A and B, and you add both A and B to the stack, but go down B first, and then B points to A and C. You'll end up visiting C and then A, and then when you navigate back "up" the graph you'll still have another visit to A in the stack. So this check shouldn't be necessary if it's guaranteed that each node is only pointed to by one other node.
  20. - I think the inner one just saves the program time by not adding nodes to the stack that we know have already been visited. It isn't necessary, as the outer check would catch those nodes anyway, but this way we don't have to do the .pop() operation for those nodes.
  21. """
  22. def dfs_i(graph, start):
  23.     visited = set()  # A set to keep track of visited nodes
  24.     stack = [start]  # Initialize the stack with the start node
  25.  
  26.     while stack:
  27.         vertex = stack.pop()  # Pop a vertex from the stack
  28.         if vertex not in visited:
  29.             visited.add(vertex)  # Mark the vertex as visited
  30.             print(vertex)  # Process the vertex (e.g., print it)
  31.  
  32.             # Add neighbors of the vertex to the stack if they haven't been visited
  33.             for neighbor in graph[vertex]:
  34.                 if neighbor not in visited:
  35.                     stack.append(neighbor)
  36.  
  37. graph = {
  38.     1 : [2, 3],
  39.     2 : [4, 5],
  40.     3 : [],
  41.     4 : [5],
  42.     5 : [1],
  43. }
  44. dfs_i(graph, 1)  # Start DFS from vertex 1
Advertisement
Add Comment
Please, Sign In to add comment