101 Logo
onenoughtone

Introduction to Depth-First Search

What is Depth-First Search?

Depth-First Search (DFS) is a graph traversal algorithm that explores as far as possible along each branch before backtracking.

In simpler terms, DFS explores a path all the way to its end before moving on to the next path, going deep before going wide.

Key Characteristics

  • Stack-Based: Uses a stack data structure (or recursion) to keep track of vertices to visit
  • Deep Exploration: Explores as far as possible along each branch before backtracking
  • Memory Efficient: Requires less memory than breadth-first search
  • Not Optimal for Shortest Paths: Does not guarantee the shortest path in unweighted graphs
  • Complete: Will find a solution if one exists in a finite graph

How DFS Works

  1. Start at a source vertex and mark it as visited
  2. Explore one of its unvisited neighbors
  3. Continue this process, always exploring an unvisited neighbor of the most recently visited vertex
  4. When a vertex has no unvisited neighbors, backtrack to the previous vertex and explore its other neighbors
  5. Repeat until all vertices reachable from the source are visited

Basic DFS Implementation

Here's a simple recursive implementation of DFS for a graph represented as an adjacency list:

function dfs(graph, startVertex) { // Set to keep track of visited vertices const visited = new Set(); // Result array to store the DFS traversal order const result = []; // Recursive helper function function dfsHelper(vertex) { // Mark the vertex as visited visited.add(vertex); // Process the vertex (add to result) result.push(vertex); // Explore all adjacent vertices for (const neighbor of graph[vertex]) { // If this neighbor has not been visited yet if (!visited.has(neighbor)) { // Recursively visit the neighbor dfsHelper(neighbor); } } } // Start DFS from the start vertex dfsHelper(startVertex); return result; } // Example usage: const graph = { 'A': ['B', 'C'], 'B': ['A', 'D', 'E'], 'C': ['A', 'F'], 'D': ['B'], 'E': ['B', 'F'], 'F': ['C', 'E'] }; const traversalOrder = dfs(graph, 'A'); console.log(traversalOrder); // Output: ['A', 'B', 'D', 'E', 'F', 'C']

Iterative DFS Implementation

Here's an iterative implementation of DFS using a stack:

function dfsIterative(graph, startVertex) { // Set to keep track of visited vertices const visited = new Set(); // Stack for DFS (using array as stack) const stack = [startVertex]; // Result array to store the DFS traversal order const result = []; // Mark the start vertex as visited visited.add(startVertex); // While there are vertices in the stack while (stack.length > 0) { // Pop a vertex from the stack const currentVertex = stack.pop(); // Process the vertex (add to result) result.push(currentVertex); // Get all adjacent vertices of the popped vertex // Add unvisited neighbors to the stack in reverse order // (to match the recursive implementation) for (const neighbor of [...graph[currentVertex]].reverse()) { if (!visited.has(neighbor)) { // Mark it as visited and push it to the stack visited.add(neighbor); stack.push(neighbor); } } } return result; } // Example usage: const traversalOrderIterative = dfsIterative(graph, 'A'); console.log(traversalOrderIterative); // Output: ['A', 'B', 'D', 'E', 'F', 'C']

Time and Space Complexity

Time Complexity:

O(V + E), where V is the number of vertices and E is the number of edges in the graph.

We visit each vertex once and each edge once.

Space Complexity:

O(V), where V is the number of vertices in the graph.

In the worst case, the stack might contain all vertices of the graph. For recursive implementation, the call stack might grow to size V.

Applications of DFS

  • Backtracking: Solving puzzles, generating mazes, and combinatorial problems
  • Cycle Detection: Finding cycles in a graph
  • Topological Sorting: Ordering vertices such that for every directed edge (u, v), vertex u comes before v
  • Connected Components: Finding all connected components in a graph
  • Pathfinding: Finding a path between two vertices
  • Strongly Connected Components: Finding strongly connected components in a directed graph
IntroVisualizePatternsPractice
101 Logo
onenoughtone