DSA

Topological sort - DFS

Graphs. Time O(N), Space O(V+E).

August 8, 2026

Practice Link

Topological Sort is a linear ordering of nodes such that if edge u -> v exists, then u appears before v.

In-degree of a node: Number of incoming edges for a node

Alt text

In-degree of node 0: 0

In-degree of node 1: 1

In-degree of node 2: 3

In-degree of node 3: 1

Sample#

Alt text

[0,1,4,2,3]

Note#

Graph can also be disconnected -> Check for every node as source/starting node.

This can be possible only for DAG ( Directed acyclic graph) because in an undirected graph we can’t decide which node will come first because there will be no direction, and if there is a cycle topological order will not be possible (See below figure to understand why it is not possible for graphs containing cycle). For reference, see below image.

exception-case

DFS#

The DFS approach uses post-order processing: a node is placed on the stack only after all of its descendants have been fully explored. This guarantees that when we read the stack top-to-bottom, every node u appears before every node v such that edge u → v exists — which is exactly the topological order definition. The stack reverses the DFS finish-time ordering into the correct left-to-right sequence.

  • Use a visited array and a stack to track the order of completion.
  • For every unvisited node, run DFS and recursively visit all unvisited neighbors first.
  • Add node u to the stack only once all adjacent nodes are fully explored (post-order).
  • Pop the stack into a result array to get the topological ordering (handles disconnected graphs by iterating over all nodes).
void DFS(adj, vis, stk, u)
{
    vis[u]= truel
    for(auto vL adj[u])
        if(!vis[v])
            DFS(adj, vis, stk, v)

    stk.push(u)
}

Implementation#

void DFS(vector<vector<int>>& adj, vector<bool> &vis, int currNode, stack<int> &stk)
    {
        vis[currNode] = true;
        
        for(auto adjNode: adj[currNode])
        {
            if(!vis[adjNode])
                DFS(adj, vis, adjNode, stk);
        }
        stk.push(currNode);
    }
  
    // Function to return list containing vertices in Topological order.
    vector<int> topologicalSort(vector<vector<int>>& adj) {
       stack<int> stk;
       vector<bool> vis(adj.size(), false);

       //covering all disconnected components as well.
       for(int i=0;i<adj.size();i++)
       {
           if(!vis[i])
                DFS(adj, vis, i, stk);

       }
       
       vector<int> topoSort;
       while(!stk.empty())
       {
           topoSort.push_back(stk.top());
           stk.pop();
       }
       return topoSort;
    }

Complexities#

Time Complexity: O(V+E) + O(N)#

We are exploring every vertex V and exploring all its edges. O(N) -> For covering disconnected components

Same TC as DFS

Space Complexity: O(N)+O(V+E),#

O(N) to keep visited nodes, and O(V+E) to create the adjacency list.