1

I am bit confused after reading examples at DFS where output is printed in different fashion for both DFS approaches though both are said to be DFS.

In fact DFS recursion approach print the output just in same fashion as BFS. Then what's the difference ? Is recursion approach given here not an example of DFS ?

enter image description here

Using Stack

// Iterative DFS using stack
    public  void dfsUsingStack(Node node)
    {
        Stack<Node> stack=new  Stack<Node>();
        stack.add(node);
        node.visited=true;
        while (!stack.isEmpty())
        {
            Node element=stack.pop();
            System.out.print(element.data + " ");

            List<Node> neighbours=element.getNeighbours();
            for (int i = 0; i < neighbours.size(); i++) {
                Node n=neighbours.get(i);
                if(n!=null && !n.visited)
                {
                    stack.add(n);
                    n.visited=true;

                }
            }
        }
    }

Output is 40,20,50,70,60,30,10

Recursion Approach

// Recursive DFS
    public  void dfs(Node node)
    {
        System.out.print(node.data + " ");
        List neighbours=node.getNeighbours();
        node.visited=true;
        for (int i = 0; i < neighbours.size(); i++) {
            Node n=neighbours.get(i);
            if(n!=null && !n.visited)
            {
                dfs(n);
            }
        }
    }

output is 40,10,20,30,60,50,70 which is same as output under BFS

So what's the difference ?

Dominique Fortin
  • 2,212
  • 15
  • 20
user3198603
  • 5,528
  • 13
  • 65
  • 125
  • 1
    You might want to include the graph you are traversing as part of that question. Otherwise, the list of visited nodes is pretty well meaningless. – rici Jul 01 '18 at 05:24
  • In some graphs DFS and BFS will produce the same traversal order. Nothing wrong with that. What graph are you traversing? – AnT stands with Russia Jul 01 '18 at 05:31
  • Adding to @AnT's answer: Due to the order in which neighbors/edges are added to the graph, it is also just a coincidence that both BFS and reversed DFS (or pseudo-DFS, as AnT calls it) traverse the same nodes at the same time. If the visitation order of neighbors in your BFS implementation is reversed, you'll get a different result. – EvilTak Jul 01 '18 at 05:31
  • You are making something up. Either your picture is incorrect, or your second output is incorrect, or something else is incorrect. If the second implementation decided to start with `40, 10, ...`, then it would invariably have to go to `30` next: `40, 10, 30...`. Yet you are claiming that your second implementation somehow produced `40,10,20,30,60,50,70`. This is impossible. I suspect that edge `10-30` does not really exist in your actual data. – AnT stands with Russia Jul 01 '18 at 06:05
  • @AnT I have given the links where image is taken from and output is based on the same program – user3198603 Jul 01 '18 at 06:15
  • @user3198603: Great! Now, look at the output at your link: `The DFS traversal of the graph using recursion: 40 10 30 60 70 20 50`. It begins with `40 10 30 ...` exactly as I predicted. Yet, in your question you are claiming that the output of the recursive version is `40,10,20,30,60,50,70`. Where did this output come from? As I said, you are making something up. – AnT stands with Russia Jul 01 '18 at 06:19

2 Answers2

4

While the end result (a path) may be the same, the root difference between bfs and dfs (not the specific implementations posted) is in the search mechanism.
An obvious example is a case when only one path exists. In such case any good search algorithm (be it dfs, bfs or other) will eventually find that one path.
Where multiple path exist, bfs and dfs may find the same path or different paths. One of the charectaristics of bfs is that it finds the shortest path.
The core difference in the search mechanism is that bfs explores equally in all directions (hence the term breadth) , while dfs explores one (typically random) direction, all the way (hence the term depth) and "backtracks" if no solution found.
There are many resources which show visual representation of bfs and dfs such as this one.
Here is a screen capture of a tool I created to demonstrate and test traversal algorithms:

enter image description here

By looking at the grey dots which represent explored nodes, you can see the nature of the bfs, which analog to water flood.

enter image description here

c0der
  • 18,467
  • 6
  • 33
  • 65
2

The first approach is not DFS at all, at least in the canonical definition of DFS algorithm. It is simply BFS in which someone replaced a queue with a stack. However, this implementation is good enough to "mimic" DFS in a sense that it discovers graph vertexes in DFS-like order. It can be called "pseudo-DFS", if you wish, because of DFS-like discovery order, but canonical DFS algorithm is much more than that.

The canonical DFS not only follows depth-first vertex discovery order, but also produces certain "undiscovery" order, certain backtracking order (i.e. the moment when "gray" vertex becomes "black" vertex in classic Dijkstra's nomenclature). In the first implementation this important feature of canonical DFS is not present (or it is impossible to implement in any reasonable way).

Meanwhile, the second approach is an explicitly recursive implementation of the classic DFS algorithm.

In any case, real DFS or pseudo-DFS, there's no "one true order" in which the vertices should be visited. Both implementations can be made to produce the same vertex visitation order. In your case nobody simply bothered to ensure that. The difference in output is caused by simple fact that the former implementation visits neighbors in reverse order - from last to first. All neighbors are first pushed into a stack and then popped one-by-one for visitation purposes. The LIFO behavior of the stack is what produces the reversal. Meanwhile, the latter implementation visits neighbors in their forward order - from first to last.

If you replace the cycle in the latter implementation with

for (int i = neighbours.size() - 1; i >= 0; --i) 

you should end up with identical visitation order (identical output) in both implementations.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765