Depth First Search Algorithm
Data structures like trees and graphs are traversed or explored by the depth-first search algorithm, or DFS. The algorithm starts at the root node (in the case of a graph, you can choose any random node as the root node) and analyses each branch as far as it can go before backtracking. This article will briefly discuss DFS and how it works.
The process of visiting each vertex (node) in a graph is known as graph traversal. A smaller graph is relatively simple to navigate. However, the process must be automated when navigating a graph with many nodes. Manual processes increase the likelihood of missing one or more vertices. And visiting nodes in a graph becomes crucial when you need to modify certain nodes, retrieve a value that was stored there, or do something else. Our graph traversing methods can help in this situation.
Two techniques exist for navigating a graph data structure:
- DFS, or the Depth-First Search algorithm
- BFS or the Breadth-First Search algorithm
Also Read: All you need to know about Data Structure and Algorithm
Also Read: Data Structures and Algorithms Online Courses & Certifications
Table of Content
Best-suited Data Structures and Algorithms courses for you
Learn Data Structures and Algorithms with these high-rated online courses
What is Depth First Search Algorithm (DFS)
Data structures like trees and graphs are traversed or explored by the depth-first search algorithm, or DFS. The algorithm starts at the root node (in the case of a graph, you can choose any random node as the root node) and analyses each branch as far as it can go before backtracking.
Also Read: What are Algorithms
Also Read: Bubble Sort Algorithm
How does the DFS algorithm work?
This is how the DFS algorithm operates:
- Start by keeping any vertex of the graph on top of the stack.
- Add the item at the top of the stack to the visited list.
- Make a list of the nodes that are close to that vertex. Place the items that havenβt been visited at the top of the stack.
- Repeat actions 2 and 3 until the stack is completely gone.
Also Read: Selection Sort Algorithm
Also Read: Quick Sort Algorithm
Traversal of all Vertices
Now that you have learned about the basics of depth-first search. Letβs see one of the basic use cases of DFS, which is traversing all vertices in a graph.
Consider an example graph given below:
Now the task is to start traversing this graph from node A and access each node using the DFS algorithm. We will cover it in the form of steps:
As mentioned above, we will use stack to complete our traversal.
Before proceeding, letβs have some assumptions throughout the process to keep the explanations simple.
- Each node is represented with a different color.
Also Read: Merge Sort Algorithm
Also Read: Insertion Sort Algorithm
Steps to traverse:
- Pick βAβ and put it into the stack.
- Remove βAβ from the stack and put its adjacent nodes (βBβ, βDβ, βCβ, and βGβ) into the stack. Mark βAβ visited (the visited nodes are represented in red color) and print it in output.
3. Consider the top element of the stack βGβ, remove it from the stack, and put the adjacent nodes of βGβ (βCβ and βAβ) into the stack. Mark βGβ as visited and print it in output.
4. The top of the stack is βAβ; remove βAβ from the stack. Before traversing towards βAβ, check if this node is visited or not. Since βAβ is already visited so you do not need to revisit it, and we can ignore it.
5. Pop βCβ and check if it visited or not. Since βCβ is not visited, add the adjacent node of βCβ (βEβ, βAβ, and βGβ) to the stack. Mark βCβ as visited and print it in output.
6. The top of the stack is βGβ; remove βGβ from the stack. Before traversing towards βGβ, check if this node is visited or not. Since βGβ is already visited so, you do not need to revisit it, and we can ignore it.
7. Now the top of the stack is βAβ; remove βAβ from the stack. Before traversing towards βAβ, check if this node is visited or not. Since βAβ is already visited so, you do not need to revisit it, and we can ignore it. The stack looks like this.
8. Now come back to βCβ and check if any edge is left; we have βEβ left. Pop βEβ and check if it visited or not. Since βEβ is not visited, add the adjacent node of βEβ (βFβ, βBβ, βDβ, and βCβ) and add it to the stack. Mark βEβ as visited and print it in output.
9. The top of the stack is βCβ; remove βCβ from the stack. Before traversing towards βCβ, check if this node is visited or not. Since βCβ is already visited so, you do not need to revisit it, and we can ignore it.
10. The top of the stack is βDβ; remove βDβ from the stack. Pop βDβ and check if visited or not. Since βDβ is not visited, add the adjacent node of βDβ (βEβ and βAβ) and add it to the stack. Mark βDβ as visited and print it in output.
11. Now the top of the stack is βAβ; remove βAβ from the stack. Before traversing towards βAβ, check if this node is visited or not. Since βAβ is already visited so, you do not need to revisit it, and we can ignore it.
12. The top of the stack is βEβ; remove βEβ from the stack. Before traversing towards βEβ, check if this node is visited or not. Since βEβ is already visited so, you do not need to revisit it, and we can ignore it. The stack looks like this.
13. Now come back to βEβ and check if any edge is left; we have βBβ and βFβ left, as seen in the stack. Pop βBβ and check if it visited or not. Since βBβ is not visited, add the adjacent node of βBβ (βFβ, βEβ, and βAβ) and add it to the stack. Mark βBβ as visited and print it in output.
14. Now the top of the stack is βAβ; remove βAβ from the stack. Before traversing towards βAβ, check if this node is visited or not. Since βAβ is already visited so, you do not need to revisit it, and we can ignore it. The stack looks like this.
15. The top of the stack is βEβ; remove βEβ from the stack. Before traversing towards βEβ, check if this node is visited or not. Since βEβ is already visited so, you do not need to revisit it, and we can ignore it.
16. The top of the stack is βFβ; remove βFβ from the stack. Pop βFβ and check if it visited or not. Since βFβ is not visited, add the adjacent node of βFβ (βEβ and βBβ) and add it to the stack. Mark βFβ as visited and print it in output.
17. Now the top of the stack is βBβ; remove βBβ from the stack. Before traversing towards βBβ, check if this node is visited or not. Since βBβ is already visited so, you do not need to revisit it, and we can ignore it.
18. The top of the stack is βEβ; remove βEβ from the stack. Before traversing towards βEβ, check if this node is visited or not. Since βEβ is already visited so, you do not need to revisit it, and we can ignore it.
19. All nodes present in the stack have been visited, you can check it in sequence, and at the end stack gets empty, and the final transversal output looks like this:
Pseudo Code
//Pseudo code for DFSDFS(adjacent[][], source, visited[], key) { if(source == key) return true //We found the key visited[source] = True FOR node in adjacent[source]: IF visited[node] == False: DFS(adjacent, node, visited) END IF END FOR return false // If it reaches here, then all nodes have been explored and we still havent found the key.}
Following is the java implementation of the DFS algorithm:
import java.io.*;import java.util.*; //Representing directed graph using adjacency// list representationclass Graph { private int V; // No. of vertices private LinkedList\n \n <integer>\n \n adjacency[];\n \n \n \n // Constructor\n \n Graph(int v)\n \n {\n \n V = v;\n \n adjacency = new LinkedList[v];\n \n for (int i = 0; i < v; ++i)\n \n adjacency[i] = new LinkedList();\n \n }\n \n \n \n // Function to add an edge into the graph\n \n void addEdge(int v, int w)\n \n {\n \n adjacency[v].add(w); // Add w to v's list.\n \n }\n \n \n \n // A function used by DFS\n \n void dfs(int v, boolean visited[])\n \n {\n \n // Mark the current node as visited and print it\n \n visited[v] = true;\n \n System.out.print(v + " ");\n \n \n \n // Recur for all the vertices adjacent to this\n \n // vertex\n \n Iterator\n \n \n \n <integer>\n \n i = adjacency[v].listIterator();\n \n while (i.hasNext()) {\n \n int n = i.next();\n \n if (!visited[n])\n \n dfs(n, visited);\n \n }\n \n }\n \n \n \n // The function to do DFS traversal. It uses recursive\n \n // dfs()\n \n void depthFirst()\n \n {\n \n // Mark all the vertices as not visited(set as\n \n // false by default in java)\n \n boolean visited[] = new boolean[V];\n \n \n \n // Call the recursive helper function to print DFS\n \n // traversal starting from all vertices one by one\n \n for (int i = 0; i < V; ++i)\n \n if (visited[i] == false)\n \n dfs(i, visited);\n \n }\n \n \n \n public static void main(String args[])\n \n {\n \n Graph grp = new Graph(4);\n \n \n \n grp.addEdge(0, 1);\n \n grp.addEdge(0, 2);\n \n grp.addEdge(1, 2);\n \n grp.addEdge(2, 3);\n \n grp.addEdge(3, 4);\n \n grp.addEdge(4, 1);\n \n \n \n // Function call\n \n grp.depthFirst();\n \n }\n \n }\n \n \n \n \n \n </integer>\n \n \n \n </integer>
Application of DFS Algorithm
The following uses for the DFS algorithm are listed:
- The topological sorting can be implemented using the DFS algorithm.
- It can be applied to determine the routes connecting two vertices.
- It can also be used to find graph cycles.
- DFS technique is also applied to puzzles with a single solution.
Also Read: All about Heap Sort Technique
Also Read: Divide and Conquer Algorithm
Conclusion
In this article, we have briefly discussed how Depth First Search Algorithm works and its application.
Hope you will like the article.
This is a collection of insightful articles from domain experts in the fields of Cloud Computing, DevOps, AWS, Data Science, Machine Learning, AI, and Natural Language Processing. The range of topics caters to upski... Read Full Bio