Topological sort using DFS

Last Updated : 31 Oct, 2025

Given a Directed Acyclic Graph(DAG), find any Topological Sorted order of the graph.

Topological Sorted order: It is a linear ordering of vertices such that for every directed edge u -> v, where vertex u comes before v in the ordering.
There can be several topological ordering for a graph.

Example:

Input: adj[][]= [[1], [], [1], [2], [2]]

frame_3269

Output: [4, 3, 2, 0, 1]
Explanation: By following that: for an edge u->v, u must come before v, we can obtain several topological orderings and [4, 3, 2, 0, 1] is one of them.

Input: V=5 , adj[][] = [[1], [2], [], [2, 4], []]

420046874


Output: [0, 3, 1, 4, 2]
Explanation: By following that: for an edge u->v, u must come before v, we can obtain several topological orderings and [0, 3, 1, 4, 2] is one of them.

[Approach]

The idea is to perform a DFS traversal starting from every unvisited vertex (from 0 to n − 1). For each DFS call, we first explore all unvisited neighbors of the current node. Once the recursive calls for all its neighbors are complete, we start pushing these nodes into a stack while backtracking. After all vertices are processed, we pop elements from the stack one by one into a list — this gives a valid topological ordering, as each node is placed before all nodes it points to.

Illustration of the algorithm:

Below is the implementation of the above algorithm. 

C++
//Driver Code Starts
#include <iostream>
#include <vector>
#include <stack>
using namespace std;

//Driver Code Ends

void findTopoSort(int node, vector<int>& vis, vector<vector<int>>& adj, stack<int>& st) {
    vis[node] = 1;
    for (int it : adj[node]) {
        if (!vis[it]) {
            findTopoSort(it, vis, adj, st);
        }
    }
    // push the node after all its neighbours
    st.push(node);
}

vector<int> topoSort(vector<vector<int>>& adj) {
    int n = adj.size();
    stack<int> st;
    vector<int> vis(n, 0);

    for (int i = 0; i < n; i++) {
        if (!vis[i]) {
            findTopoSort(i, vis, adj, st);
        }
    }
    vector<int> topo;
    
    // popping elements from stack and 
    // pushing into the list
    while (!st.empty()) {
        topo.push_back(st.top());
        st.pop();
    }
    return topo;
}

//Driver Code Starts

void addEdge(vector<vector<int>>& adj, int u, int v) {
    adj[u].push_back(v);
}

int main() {
    int n = 5;
    vector<vector<int>> adj(n);
    
    // adding edges to adjacency list
    addEdge(adj, 0, 1);
    addEdge(adj, 2, 1);
    addEdge(adj, 3, 2);
    addEdge(adj, 4, 2);

    vector<int> res = topoSort(adj);
    for (int vertex : res)
        cout << vertex << " ";
    cout << endl;
}

//Driver Code Ends
Java
//Driver Code Starts
import java.util.ArrayList;
import java.util.Stack;

class Solution {
//Driver Code Ends

    static void findTopoSort(int node, int[] vis, ArrayList<ArrayList<Integer>> adj, Stack<Integer> st) {
        vis[node] = 1;
        for (Integer it : adj.get(node)) {
            if (vis[it] == 0) {
                findTopoSort(it, vis, adj, st);
            }
        }
        // Push the node after visiting 
        // all its neighbours
        st.push(node);
    }

    static ArrayList<Integer> topoSort(ArrayList<ArrayList<Integer>> adj) {
        int n = adj.size();
        Stack<Integer> st = new Stack<>();
        int[] vis = new int[n];

        for (int i = 0; i < n; i++) {
            if (vis[i] == 0) {
                findTopoSort(i, vis, adj, st);
            }
        }

        ArrayList<Integer> topo = new ArrayList<>();
        
        // popping elements from stack and 
        // pushing into the list
        while (!st.isEmpty()) {
            topo.add(st.pop());
        }
        return topo;
    }

//Driver Code Starts

    static void addEdge(ArrayList<ArrayList<Integer>> adj, int u, int v) {
        adj.get(u).add(v);
    }

    public static void main(String[] args) {
        int n = 5; 
        ArrayList<ArrayList<Integer>> adj = new ArrayList<>();

        for (int i = 0; i < n; i++)
            adj.add(new ArrayList<>());
        
        
        // adding edges to adjacency list
        addEdge(adj, 0, 1);
        addEdge(adj, 2, 1);
        addEdge(adj, 3, 2);
        addEdge(adj, 4, 2);
        
        ArrayList<Integer> res = topoSort(adj);

        for (int vertex : res) {
            System.out.print(vertex + " ");
        }
        System.out.println();
    }
}

//Driver Code Ends
Python
def findTopoSort(node, vis, adj, stack):
    vis[node] = 1
    for it in adj[node]:
        if vis[it] == 0:
            findTopoSort(it, vis, adj, stack)
    
    # push the node after all its neighbours
    stack.append(node)

def topoSort(adj):
    n = len(adj)
    stack = []
    vis = [0] * n

    for i in range(n):
        if vis[i] == 0:
            findTopoSort(i, vis, adj, stack)

    topo = []
    
    # popping elements from stack and 
    # pushing into the list
    while stack:
        topo.append(stack.pop())
    
    return topo


#Driver Code Starts

def addEdge(adj, u, v):
    adj[u].append(v)


if __name__ == "__main__":
    n = 5
    adj = [[] for _ in range(n)]
    
    # adding edges to adjacency list
    addEdge(adj, 0, 1)
    addEdge(adj, 2, 1)
    addEdge(adj, 3, 2)
    addEdge(adj, 4, 2)
    
    res = topoSort(adj)
    print(*res)

#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;

class GFG {
//Driver Code Ends

    static void findTopoSort(int node, int[] vis, List<List<int>> adj, Stack<int> st) {
        vis[node] = 1;
        foreach (int it in adj[node]) {
            if (vis[it] == 0) {
                findTopoSort(it, vis, adj, st);
            }
        }

        // push the node after all its neighbours
        st.Push(node);
    }

    static List<int> topoSort(List<List<int>> adj) {
        int n = adj.Count;
        Stack<int> st = new Stack<int>();
        int[] vis = new int[n];

        for (int i = 0; i < n; i++) {
            if (vis[i] == 0) {
                findTopoSort(i, vis, adj, st);
            }
        }
        List<int> topo = new List<int>();
        
        // popping elements from stack and 
        // pushing into the list
        while (st.Count > 0) {
            topo.Add(st.Pop());
        }
        return topo;
    }

//Driver Code Starts

    public static void addEdge(List<List<int>> adj, int u, int v) {
        adj[u].Add(v);
    }

    public static void Main(string[] args) {
        int n = 5;
        List<List<int>> adj = new List<List<int>>();
        for (int i = 0; i < n; i++)
            adj.Add(new List<int>());

        // adding edges to adjacency list
        addEdge(adj, 0, 1);
        addEdge(adj, 2, 1);
        addEdge(adj, 3, 2);
        addEdge(adj, 4, 2);

        List<int> res = topoSort(adj);
        foreach (int vertex in res)
            Console.Write(vertex + " ");
        Console.WriteLine();
    }
}

//Driver Code Ends
JavaScript
function findTopoSort(node, vis, adj, stack) {
    vis[node] = 1;
    for (let it of adj[node]) {
        if (vis[it] === 0) {
            findTopoSort(it, vis, adj, stack);
        }
    }

    // push the node after all its neighbours
    stack.push(node);
}

function topoSort(adj) {
    let n = adj.length;
    let stack = [];
    let vis = new Array(n).fill(0);

    for (let i = 0; i < n; i++) {
        if (vis[i] === 0) {
            findTopoSort(i, vis, adj, stack);
        }
    }

    let topo = [];
    
    // popping elements from stack and 
    // pushing into the list
    while (stack.length > 0) {
        topo.push(stack.pop());
    }
    return topo;
}


//Driver Code Starts
function addEdge(adj, u, v) {
    adj[u].push(v);
}

// Driver code

let n = 5;
let adj = Array.from({ length: n }, () => []);


// adding edges to adjacency list
addEdge(adj, 0, 1);
addEdge(adj, 2, 1);
addEdge(adj, 3, 2);
addEdge(adj, 4, 2);

let res = topoSort(adj);
console.log(res.join(" "));

//Driver Code Ends

Output
4 3 2 0 1 

Time Complexity: O(V+E). We visited all the nodes, and all the neighbours of each node(i.e., all the edges).
Auxiliary Space: O(V). For visited array, and for stack to store the topological order.

Comment