Travel means visiting all nodes of the graph. Depth Traversal or Depth First Search is a recursive algorithm for finding all the vertices of a graph or tree data structure. In this article, with the help of the examples below, you will learn: DFS algorithm, DFS pseudocode, and DFS algorithm code with implementation in C++, C, Java, and Python programs.
Algorithm DFS
The standard implementation of DFS puts each graph vertex into one of two categories:
- Visited.
- Not visited.
The purpose of the algorithm is to mark each vertex as visited, avoiding cycles.
The DFS algorithm works like this:
- Start by placing any vertex of the graph on top of the stack.
- Take the top element of the stack and add it to the visited list.
- Create a list of adjacent nodes of this vertex. Add those not in the visited list to the top of the stack.
- Continue repeating steps 2 and 3 until the stack is empty.
Example DFS
Let's see how the depth-first search algorithm works with an example. We are using an undirected graph with 5 vertices.
We start at node 0, the DFS algorithm starts by placing it in the visited list and placing all adjacent nodes on the stack.
We then visit the element at the top of the stack, i.e. 1, and move on to adjacent nodes. Since we have already visited 0, we visit 2 instead.
Vertex 2 has an unvisited adjacent node 4, so we add it to the top of the stack and visit it.
After we visit the last element 3, it has no unvisited adjacent nodes. This concludes the first “depth-first traversal” of the graph.
DFS pseudo-code (recursive implementation)
The pseudocode for DFS is shown below. Note that in the init() function, we start the DFS function on each node. This is because a graph can have two different unconnected parts, so to make sure we cover every vertex, we can also run the DFS algorithm on every node.
DFS(G, u) u.visited = true for each v ∈ G.Adj[u] if v.visited == false DFS(G,v) init() { For each u ∈ G u.visited = false For each u ∈ G DFS(G, u) }
DFS code
The code for the DFS algorithm with an example is shown below. The code has been simplified so we can focus on the algorithm and not other details.
DFS в C
#include <stdio.h> #include <stdlib.h> struct node { int vertex; struct node* next; }; struct node* createNode(int v); struct Graph { int numVertices; int* visited; struct node** adjLists; // we need int** to store a two dimensional array. Similary, we need struct node** to store an array of Linked lists }; struct Graph* createGraph(int); void addEdge(struct Graph*, int, int); void printGraph(struct Graph*); void DFS(struct Graph*, int); int main() { struct Graph* graph = createGraph(4); addEdge(graph, 0, 1); addEdge(graph, 0, 2); addEdge(graph, 1, 2); addEdge(graph, 2, 3); printGraph(graph); DFS(graph, 2); return 0; } void DFS(struct Graph* graph, int vertex) { struct node* adjList = graph->adjLists[vertex]; struct node* temp = adjList; graph->visited[vertex] = 1; printf("Visited %d \n", vertex); while(temp!=NULL) { int connectedVertex = temp->vertex; if(graph->visited[connectedVertex] == 0) { DFS(graph, connectedVertex); } temp = temp->next; } } struct node* createNode(int v) { struct node* newNode = malloc(sizeof(struct node)); newNode->vertex = v; newNode->next = NULL; return newNode; } struct Graph* createGraph(int vertices) { struct Graph* graph = malloc(sizeof(struct Graph)); graph->numVertices = vertices; graph->adjLists = malloc(vertices * sizeof(struct node*)); graph->visited = malloc(vertices * sizeof(int)); int i; for (i = 0; i < vertices; i++) { graph->adjLists[i] = NULL; graph->visited[i] = 0; } return graph; } void addEdge(struct Graph* graph, int src, int dest) { // Add edge from src to dest struct node* newNode = createNode(dest); newNode->next = graph->adjLists[src]; graph->adjLists[src] = newNode; // Add edge from dest to src newNode = createNode(src); newNode->next = graph->adjLists[dest]; graph->adjLists[dest] = newNode; } void printGraph(struct Graph* graph) { int v; for (v = 0; v < graph->numVertices; v++) { struct node* temp = graph->adjLists[v]; printf("\n Adjacency list of vertex %d\n ", v); while (temp) { printf("%d -> ", temp->vertex); temp = temp->next; } printf("\n"); } }
Depth First Search (DFS) в C++
#include <iostream> #include <list> using namespace std; class Graph { int numVertices; list *adjLists; bool *visited; public: Graph(int V); void addEdge(int src, int dest); void DFS(int vertex); }; Graph::Graph(int vertices) { numVertices = vertices; adjLists = new list[vertices]; visited = new bool[vertices]; } void Graph::addEdge(int src, int dest) { adjLists[src].push_front(dest); } void Graph::DFS(int vertex) { visited[vertex] = true; list adjList = adjLists[vertex]; cout << vertex << " "; list::iterator i; for(i = adjList.begin(); i != adjList.end(); ++i) if(!visited[*i]) DFS(*i); } int main() { Graph g(4); g.addEdge(0, 1); g.addEdge(0, 2); g.addEdge(1, 2); g.addEdge(2, 3); g.DFS(2); return 0; }
DFS Java code
import java.io.*; import java.util.*; class Graph { private int numVertices; private LinkedList<Integer> adjLists[]; private boolean visited[]; Graph(int vertices) { numVertices = vertices; adjLists = new LinkedList[vertices]; visited = new boolean[vertices]; for (int i = 0; i < vertices; i++) adjLists[i] = new LinkedList<Integer>(); } void addEdge(int src, int dest) { adjLists[src].add(dest); } void DFS(int vertex) { visited[vertex] = true; System.out.print(vertex + " "); Iterator ite = adjLists[vertex].listIterator(); while (ite.hasNext()) { int adj = ite.next(); if (!visited[adj]) DFS(adj); } } public static void main(String args[]) { Graph g = new Graph(4); g.addEdge(0, 1); g.addEdge(0, 2); g.addEdge(1, 2); g.addEdge(2, 3); System.out.println("Following is Depth First Traversal"); g.DFS(2); } }
DFS in Python
def dfs(graph, start, visited=None): if visited is None: visited = set() visited.add(start) print(start) for next in graph[start] - visited: dfs(graph, next, visited) return visited graph = {'0': set(['1', '2']), '1': set(['0', '3', '4']), '2': set(['0']), '3': set(['1']), '4': set(['2', '3'])} dfs(graph, '0')