×

Depth First Search Program to Traverse a Graph in C++

Depth First Search (DFS) is a technique that is used for transversing the graph. The process of Depth First Search (DFS) starts from the root node and then next comes to the adjacent nodes. This means Depth First Search (DFS) expands the node depth-wise. The traversing process stops when it encounters a node with no child node. Once the leaf nodes come then, the whole process repeats again. Unlike the BFS, the Depth First Search (DFS) also expands its process breadth-wise. We use the stack data structure to expand the whole process in Depth First Search (DFS). The unexplored nodes are also called discovery edges, while the already visited node is called block nodes.

Now, we will see the algorithm and pseudo code for the Depth First Search (DFS).

  • Step 1: We have to insert the root node in a graph of the stack.
  • Step 2: We have to pop the item from the stack and start visiting the nodes.
  • Step 3: Then, we have to find all the adjacent nodes and mark them as visited.
  • Step 4: Repeat steps two and step 3 until the whole stack becomes empty.

The pseudo-code for the Depth First Search (DFS) is below.

Procedure DFS(G,x)
 G>graph to be traversed.
  x> starting nodes.
Begin
x.visited= true
for each v belongs to G.Adj[x]
if v.visited==false
dfs ( G, v)
end procedure.
For each x belongs to G
x. visited = false
 for each x belongs to G
DFS(G,x)
}   

Traversal Process of Depth First Search (DFS) with Illusion

Let us start the discussion of the traversal of Depth First Search (DFS) in a stepwise manner. We will be going to use the same graph for the whole traversal process.

Let us take 0 as the starting node. Then, we mention 0 as the visited, then start the traversing process with 0. Then, we have to push all the neighboring nodes in manner wise in the stack.

Then, we have to perform the above process in node one, i.e., top of the stack. Then, we have to mark node one as visited then add node 1 to the marked list.

Depth First Search Program to Traverse a Graph in C++

 Now, we have to look for the adjacent node of 1. As 0 is already visited, then we have to perform the operation in node 2.

Depth First Search Program to Traverse a Graph in C++

Next, we have to mark node two as visited and add node two to the visited list.

Depth First Search Program to Traverse a Graph in C++

Next, we have to mark node four as marked and add node 4 to the visited list.

Depth First Search Program to Traverse a Graph in C++

Next, we have to mark node three as marked and add node 3 to the visited list.

Depth First Search Program to Traverse a Graph in C++

Now, the whole stack becomes empty. So, we have to stop our traversal process.

Depth First Search Program to Traverse a Graph in C++

Implementation of Depth First Search (DFS)

#include <iostream> 
#include <list> 
using namespace std; 
class DFSGraph 
{ 
int V;   
list<int> *adjList;   
void DFS_util(int v, bool visited[]);  
public: 
   
DFSGraph(int V)
    {
 this->V = V; 
 adjList = new list<int>[V]; 
    }
   
void addEdge(int v, int w){
adjList[v].push_back(w);
    }
     
void DFS();   
}; 
void DFSGraph::DFS_util(int v, bool visited[]) 
{ 
    
visited[v] = true; 
cout << v << " "; 
   
    
list<int>::iterator i; 
for(i = adjList[v].begin(); i != adjList[v].end(); ++i) 
if(!visited[*i]) 
DFS_util(*i, visited); 
} 
 
void DFSGraph::DFS() 
{ 
  
bool *visited = new bool[V]; 
for (int i = 0; i < V; i++) 
visited[i] = false; 
   
   
for (int i = 0; i < V; i++) 
if (visited[i] == false) 
DFS_util(i, visited); 
} 
   
int main() 
{ 
  
DFSGraph gdfs(5); 
gdfs.addEdge(0, 1); 
gdfs.addEdge(0, 2); 
gdfs.addEdge(0, 3);
gdfs.addEdge(1, 2); 
gdfs.addEdge(2, 4);
gdfs.addEdge(3, 3); 
gdfs.addEdge(4, 4);


cout << "Depth-first traversal for the given graph:"<<endl; 
gdfs.DFS(); 
   
return 0; 
}

Output:

Depth-first traversal for the given graph:
0 1 2 4 3

Runtime Analysis

The time complexity for Depth First Search (DFS) is O (|V|+|E|) which is similar to the breath first search. 

Here V= number of vertices.

E= number of edges given in the graph.

Handling a Disconnected Graph

The above code traverses only the vertices reachable from a given source vertex. All the vertices may not be reachable from a given vertex, as in a disconnected graph. To do a complete DFS traversal of such graphs, run DFS from all unvisited nodes after a DFS. The recursive function remains the same.

Follow the steps given below to solve the problem:

  • Create a recursive function that takes the index of the node and a visited array.
  • Mark the current node as visited and print the node.
  • Traverse all the adjacent and unmarked nodes and call the recursive function with the index of the adjacent node.
  • Run a loop from 0 to the number of vertices and check if the node is unvisited in the previous DFS, then call the recursive function with the current node.

Iterative Depth First Search (DFS)

The above Depth First Search (DFS) implementation is recursive in nature. It is used to call the function from the stack. But we have another method to implement the iterative depth-first search. We use the explicit stack method to hold the visited nodes in this method. Below we show the implementation of the iterative depth-first search method in a program.

#include<bits/stdc++.h> 
using namespace std; 
class Graph 
{ 
int V;   
list<int> *adjList;   
public: 
Graph(int V) 
    {
this->V = V; 
adjList = new list<int>[V]; 
    }
void addEdge(int v, int w)  
    {
adjList[v].push_back(w):
    }
void DFS(); 
   
    
void DFSUtil(int s, vector<bool> &visited); 
}; 
   


void Graph::DFSUtil(int s, vector<bool> &visited) 
{ 
   
stack<int> dfsstack; 
dfsstack.push(s); 
   
while (!dfsstack.empty()) 
    { 
         
        s = dfsstack.top(); 
       dfsstack.pop(); 
   
        
 if (!visited[s]) 
        { 
cout << s << " "; 
visited[s] = true; 
        } 
  
for (auto i = adjList[s].begin(); i != adjList[s].end(); ++i) 
if (!visited[*i]) 
dfsstack.push(*i); 
    } 
} 
void Graph::DFS() 
{ 
   
vector<bool> visited(V, false); 
   
for (int i = 0; i < V; i++) 
if (!visited[i]) 
DFSUtil(i, visited); 
} 
   
//main program
int main() 
{ 
    Graph gidfs(5); 
gidfs.addEdge(0, 1); 
gidfs.addEdge(0, 2); 
gidfs.addEdge(0, 3);
gidfs.addEdge(1, 2); 
gidfs.addEdge(2, 4);
gidfs.addEdge(3, 3); 
gidfs.addEdge(4, 4);
  
cout << "Output of Iterative Depth-first traversal:\n"; 
gidfs.DFS(); 
   
return 0; 
}

Output:

Output of Iterative Depth-first traversal:
0 3 2 4 1

Here, we use the same graph for the implementation of the iterative depth-first search. There is a difference in the output. It is because of the iterative implementation of a stack. As the stack flow LIFO (Last in First Out), there is a difference in the sequence of Depth First search (DFS).

Applications of DFS

  • Detecting Cycles In The Graph: If we find a back edge while performing DFS in a graph, we can conclude that the graph has a cycle. Hence DFS is used to detect the cycles in a graph.
  • Pathfinding: Given two vertices, x and y, we can find the path between x and y using DFS. We start with vertex x and then push all the vertices on the way to the stack till we encounter y. The contents of the stack give the path between x and y.
  • Minimum Spanning Tree and Shortest Path: DFS traversal of the un-weighted graph gives us a minimum spanning tree and shortest path between nodes.
  • Topological Sorting: We use topological sorting to schedule the jobs from the given dependencies among jobs. In computer science, we use it primarily to resolve symbol dependencies in linkers, data serialization, instruction scheduling, etc. DFS is widely used in Topological sorting.

Conclusion

In the last couple of tutorials, we have explored more about the two traversal techniques for graphs, i.e., BFS and DFS. We have seen the differences as well as the applications of both methods. BFS and DFS achieve the same outcome of visiting all nodes of a graph, but they differ in the order of the output and how it is done.

We have also seen the implementation of both techniques. While BFS uses a queue, DFS uses stacks to implement the method. With this, we conclude the tutorial on traversal techniques for graphs. We can also use BFS and DFS on trees.


Related Topics

Containership in C++

In C++, it is possible to create an object in one class into another class, and that object is a member of another class. This relationship is known as a...

4 minutes read.

Factorial Program in C++

C++ Factorial Program: The product of all positive descending integers is the factorial of n. n! denotes the factorial of n. For instance: 5! = 5*4*3*2*1=120 4! = 4*3*2*1=24 In Combinations and Permutations, the...

4 minutes read.

C++ Friend function

A friend function has the right to access all private and protected members of a class although it is defined outside that class' scope. Syntax class className{     ......     friend retyrn_type function_Name(argument);     .......   }   return_type function_Name(argument){     ......   } C++ friend function Example #include <iostream>   using namespace std;   class Length   {       private:           int meter;       public:           Length(): meter(5) { }           friend int addMethod(Length); //friend function declaration   };   int addMethod(Length l) // friend function definition   {       l.meter += 10; //accessing private data from non-member function       return l.meter;   }   int main()   {       Length L;       int totallength;       totallength=addMethod(L);       cout<<"Length: "<< totallength;       return 0;   } Output: Length: 15   C++ friend function...

1 minute read.

How to improve programming skills in C++

Before getting started, one should know why to improve their programming skills. To become a good software developer or programmer, one must be skilled in at least one programming language. Many...

4 minutes read.

Roadmap to C++ Programming

Introduction There are so many programming languages available in the market, but among them, C++ is something that never lost its charm. It has a powerful impact on the programming world....

4 minutes read.

C++ cin and cout

In this article, we will discuss the C++ cin and cout with their library and examples. C++ Standard Input/Output: User-program communication is made possible by C++’s usage of input and output (I/O)...

5 minutes read.

Template Specialization in C++

Template is a feature of C++. With the help of a template, we can write the code only once and use that code multiple times. For example, there is a...

4 minutes read.

Features and Use of Pointers in C/C++

What is a pointer? A pointer is mainly used to store the address of another variable. The * operator creates a pointer variable, which points to a data type (like an...

7 minutes read.

Inheritance Program in C++

What is Inheritance? Inheritance is the ability of a class to inherit traits and properties from another class. One of the most crucial aspects of Object-Oriented Programming is inheritance. The ability or...

9 minutes read.

How to make a password program in C++

Before understanding the password program, one must know about a password and why it is required. Password: A password is a word that permits access to somewhere or something. A password...

4 minutes read.

C++ | C Plus Plus While loop

In this article, we will discuss the C++ while loop with its syntax, use, key features, key points, pseudo code, and examples. What is the While Loop? The “while loop” is a...

4 minutes read.

Storage Classes in C

Storage Classes in C Storage Classes are used to define the variable and function property. These functionalities include basically the scope, accessibility, and lifetime that help us detect the existence of...

4 minutes read.

Data Hiding in C++

C++ : High-performance apps can be made using the cross-platform language C++. Bjarne Stroustrup created C++ as an addition to the C language. Programmers have extensive control over memory and system...

3 minutes read.

4 Pillars of OOPs

OOPs OOPS means Object Oriented Programming System Structure. Object oriented Programming is defined as an approach that provides a way of modularizing programs by creating partitioned memory area for both data...

11 minutes read.

Learn C++ Tutorial

C++ Introduction C++ is an object-oriented programming language. It was developed by Bjarne Stroustrup at AT&T Bell Laboratories. It is superset (extension) of C programming language. Depending upon features supported by programming...

10 minutes read.

Virtual base class in C++

Consider in a C++ program, there are 4 classes named class A, class B, class C, and class D. If class B and class c inherit properties from class A....

3 minutes read.

Observer Design Pattern in C++

The Observer design pattern is a behavioural design pattern that allows an object (known as the subject) to notify other objects (known as observers) when its state changes. This is...

3 minutes read.

C++ Queue

C++ queue: Queue in C++ is also a container adapter with the functionality of a queue. Queue is just the opposite of the stack in C++ because stack works on...

4 minutes read.

4-Dimensional Array in C/C++

A four-dimensional (4D) array is an array of three-dimensional (3D) arrays, or in other words we can say that a 4- dimensional array is an array of arrays of arrays...

3 minutes read.

How to build a program in C++

Building a program is all about creating the program and executing it successfully. There are some steps  precisely, which must be followed to make the program. Step 1: Get an IDE...

4 minutes read.