0
0
DSA Cprogramming

DFS Depth First Search on Graph in DSA C

Choose your learning style9 modes available
Mental Model
DFS explores as far as possible along each branch before backtracking. It dives deep into one path before trying others.
Analogy: Imagine exploring a maze by always taking the first unexplored path you see, going deep until you hit a dead end, then backtracking to try other paths.
Graph adjacency list:
0 -> 1 -> 2 -> null
1 -> 3 -> null
2 -> 4 -> null
3 -> null
4 -> null
↑ Start at node 0
Dry Run Walkthrough
Input: Graph with edges: 0-1, 0-2, 1-3, 2-4; start DFS at node 0
Goal: Visit all nodes reachable from node 0 in depth-first order
Step 1: Start DFS at node 0, mark 0 visited
Visited: [0]
Stack: [0]
Why: We begin exploring from node 0
Step 2: From 0, go to neighbor 1, mark 1 visited
Visited: [0, 1]
Stack: [0, 1]
Why: DFS goes deep by visiting first unvisited neighbor
Step 3: From 1, go to neighbor 3, mark 3 visited
Visited: [0, 1, 3]
Stack: [0, 1, 3]
Why: Continue deep exploration
Step 4: Node 3 has no unvisited neighbors, backtrack to 1
Visited: [0, 1, 3]
Stack: [0, 1]
Why: Dead end reached, backtrack
Step 5: Node 1 has no more unvisited neighbors, backtrack to 0
Visited: [0, 1, 3]
Stack: [0]
Why: All neighbors of 1 visited, backtrack
Step 6: From 0, go to neighbor 2, mark 2 visited
Visited: [0, 1, 3, 2]
Stack: [0, 2]
Why: Explore next neighbor of 0
Step 7: From 2, go to neighbor 4, mark 4 visited
Visited: [0, 1, 3, 2, 4]
Stack: [0, 2, 4]
Why: Go deep from 2
Step 8: Node 4 has no unvisited neighbors, backtrack to 2, then 0, then end
Visited: [0, 1, 3, 2, 4]
Stack: []
Why: All nodes visited, DFS complete
Result:
Visited order: 0 -> 1 -> 3 -> 2 -> 4
Annotated Code
DSA C
#include <stdio.h>
#include <stdbool.h>
#define MAX 5

// Graph represented as adjacency matrix
int graph[MAX][MAX] = {
    {0,1,1,0,0}, // neighbors of 0
    {0,0,0,1,0}, // neighbors of 1
    {0,0,0,0,1}, // neighbors of 2
    {0,0,0,0,0}, // neighbors of 3
    {0,0,0,0,0}  // neighbors of 4
};
bool visited[MAX] = {false};

void dfs(int node) {
    visited[node] = true; // mark current node visited
    printf("%d ", node); // print visited node
    for (int i = 0; i < MAX; i++) {
        if (graph[node][i] == 1 && !visited[i]) {
            dfs(i); // recursively visit neighbor
        }
    }
}

int main() {
    dfs(0); // start DFS at node 0
    printf("\n");
    return 0;
}
visited[node] = true; // mark current node visited
mark current node as visited to avoid revisiting
printf("%d ", node); // print visited node
output the node as we visit it
for (int i = 0; i < MAX; i++) {
check all possible neighbors of current node
if (graph[node][i] == 1 && !visited[i]) {
if neighbor exists and not visited, explore it
dfs(i); // recursively visit neighbor
go deep into neighbor node
OutputSuccess
0 1 3 2 4
Complexity Analysis
Time: O(V + E) because DFS visits every vertex and edge once
Space: O(V) for the visited array and recursion stack in worst case
vs Alternative: Compared to BFS which uses a queue and explores level by level, DFS uses recursion and explores depth first, both have similar time but different traversal order
Edge Cases
Graph with no edges (isolated nodes)
DFS visits only the start node since no neighbors exist
DSA C
if (graph[node][i] == 1 && !visited[i]) {
Graph with a single node
DFS visits the single node and ends
DSA C
visited[node] = true;
Graph with cycles
Visited array prevents infinite loops by skipping visited nodes
DSA C
if (graph[node][i] == 1 && !visited[i]) {
When to Use This Pattern
When you need to explore all nodes or paths deeply in a graph or tree, DFS is the pattern to use because it dives deep before backtracking.
Common Mistakes
Mistake: Not marking nodes as visited before recursive calls
Fix: Mark the node visited immediately when entering DFS to avoid infinite loops
Mistake: Visiting neighbors without checking if they are visited
Fix: Always check visited array before recursive DFS call
Summary
DFS visits nodes by going deep along each path before backtracking.
Use DFS when you want to explore all paths or connected components deeply.
The key insight is to mark nodes visited and recurse on neighbors to avoid cycles.