Site
Site

Reputation: 265

Does depth first search create redundancy?

I'm trying to make sense of the canonical DFS pseudocode on Wikipedia (http://en.wikipedia.org/wiki/Depth-first_search) -- in particular, the non-recursive implementation that uses a stack.

In BFS, you check whether a node is already explored before pushing it onto the queue, and this guarantees that no node will ever be pushed onto the queue more than once. But in DFS, you only check whether a node is already explored when you pop it off the stack. This seems to be deliberate, as the Wikipedia page says: "[DFS] delays checking whether a vertex has been discovered until the vertex is popped from the stack rather than making this check before pushing the vertex."

But it seems like this delay could cause nodes to be pushed onto the stack more than once. For example, consider the graph where node 1 points to node 2, which points to node 3, which points to node 4, and so on, up to node 100. Each of these nodes points to node 0.

Consider applying the Wikipedia DFS algorithm to this graph, with node 1 as the start state. First, node 0 will be pushed onto the stack. Then node 2 will be pushed. Next, node 2 will be popped off the stack, and since it has not been explored, its children will be pushed onto the stack, (without checking whether they have already been added to the stack!). Node 2's children are node 0 and node 3. Next, node 3 will be expanded, pushing node 0 and node 4 onto the stack. This will continue until the stack is filled with 100 occurrences of node 0.

My question is: why does DFS differ from BFS by delaying the explored check if it creates this redundancy?

Upvotes: 6

Views: 1400

Answers (3)

Nir Alfasi
Nir Alfasi

Reputation: 53525

My bad, I thought that the question you posed on the last sentence is about DFS in general... In this specific implementation pushing to the stack is indeed redundant and could easily be avoided by adding a if not visited condition before the 'push'.

That said, it doesn't change the amortized complexity O(|E|+|V|)

Upvotes: 1

Aivean
Aivean

Reputation: 10882

You are right, in Wikipedia's implementation of non-recursive DFS each Vertex will be put into Stack as many times as the number of incoming edges.

But I think it's not done by intention. You can see that the recursive implementation there is taken from "An Introduction to Data Structures and Algorithms" by Cormen and others. This book can be considered more "canonical" than the source of non-recursive DFS pseudocode. And you can see that target vertex there is checked before going deeper into recursion. That seems more reasonable.

So, in conclusion, I think that there is non-critical flaw in Wikipedia's implementation. It is generally good approach not to blindly believe in "canons".

Upvotes: 1

Ashu Pachauri
Ashu Pachauri

Reputation: 1403

I think you have taken the wikipedia algorithm too literally rather than thinking about what it means to visit/discover a node. In BFS also, you can push all the children/adjacent nodes of a node into the queue, but then you have to discard the ones that were already discovered; Same is the case with DFS.

In BFS and DFS, you can choose to:

  1. Not push a node that was already discovered. OR
  2. Push all adjacent nodes, but discard those nodes while popping, that were already discovered.

The only distinction between BFS and DFS is that, you are pushing on to a stack in BFS vs into a Queue in DFS.

Upvotes: 1

Related Questions