Visit a start vertex, then recurse into its first unvisited neighbour all the way down before backtracking. A visited set prevents revisiting, and neighbour insertion order fixes the visit sequence.

Algorithm

Basic Implementation

basic.cpp
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <functional>

int main() {
    std::map<int, std::vector<int>> adj;
    adj[1] = {2, 3};
    adj[2] = {1, 4};
    adj[3] = {1, 4};
    adj[4] = {2, 3, 5};
    adj[5] = {4, 6};
    adj[6] = {5};

    std::set<int> visited;
    std::vector<int> order;
    std::function<void(int)> dfs = [&](int v) {
        visited.insert(v);
        order.push_back(v);
        for (int nb : adj[v]) {
            if (visited.find(nb) == visited.end()) {
                dfs(nb);
            }
        }
    };
    dfs(1);
    std::cout << "[";
    for (size_t i = 0; i < order.size(); ++i) {
        if (i > 0) std::cout << ", ";
        std::cout << order[i];
    }
    std::cout << "]" << std::endl;
    return 0;
}

DFS follows the first unvisited neighbour as far as it can, then unwinds and tries the next branch.

Step 1 - First branch

Starting from 1, insertion order sends DFS to 2, then 4, then 3.

Early DFS descent: 1 -> 2 -> 4 -> 3.1#12#23#44#356

Step 2 - Full DFS order

The final order is [1, 2, 4, 3, 5, 6], then calls unwind 6 -> 5 -> 4 -> 3 -> 2 -> 1.

DFS order and final recursive tail.1#12#23#44#35#56#6

Complexity

  • Time: O(V + E)
  • Space: O(V) recursion depth

Implementation notes

  • C++: a recursive std::function<void(int)> lambda captures visited and order by reference; recursion depth is bounded by V.
  • The replay shows the current vertex, the visited set, the running visit order, and the call stack after each entry, matching the lesson spec.
recursive descent Follow one branch to its end, then unwind and try the next neighbour.