3.5.7Graphs

Topological sort — DFS-based, Kahn's algorithm (BFS-based)

2,230 words10 min readdifficulty · medium5 backlinks

WHAT is a topological sort?

WHY does a cycle break it? If abcaa \to b \to c \to a, then aa must come before bb, bb before cc, and cc before aa. That forces aa before aa — impossible. So cycles ⇒ no topological order.


WHY two algorithms?

Both solve the same problem but think differently:

DFS-based Kahn's (BFS-based)
Core idea A node finishes after all its descendants Repeatedly remove nodes with no remaining prerequisites
Output built In reverse finish order In arrival order
Cycle detection Back edge (gray node) Fewer than $
Data structure Recursion stack Queue + indegree array

Both run in O(V+E)O(V+E).


Algorithm 1 — DFS-based

HOW it works (derivation from first principles)

Claim: If we reverse the order in which DFS finishes vertices, every edge points forward.

Take any edge uvu \to v. When DFS first touches uu, consider vv's state:

  • vv unvisited: DFS will explore vv as a descendant of uu, so vv finishes before uu. ✅ (uu finishes later ⇒ uu earlier in reversed order)
  • vv already finished: then vv finished before uu even started. ✅
  • vv in progress (gray, on the stack): this means there's a path vuv \rightsquigarrow u already, plus edge uvu\to v = a cycle. Not allowed in a DAG. ❌ blocked.

In every valid (DAG) case, uu finishes after vv, so in the reversed finish list uu precedes vv. Edge points forward. ∎

function topoDFS(G):
    visited = {}, finished = []
    for each vertex u in V:
        if u not visited: dfs(u)
    return reverse(finished)

function dfs(u):
    mark u visited (GRAY)
    for each edge u -> v:
        if v GRAY:  report CYCLE   # back edge
        if v not visited: dfs(v)
    mark u BLACK
    finished.append(u)             # append on FINISH

Algorithm 2 — Kahn's Algorithm (BFS-based)

HOW it works (derivation)

Define indeg(v)\text{indeg}(v) = number of edges pointing into vv.

  1. A DAG always has at least one vertex with indegree 0 (else follow incoming edges backward forever ⇒ a repeat ⇒ cycle). So we can always start.
  2. Emitting a 0-indegree vertex and deleting its out-edges keeps the rest a DAG. By induction the whole graph empties out.
  3. Every edge points forward: when we emit uu, all of uu's prerequisites are already emitted; the edge uvu\to v decrements indeg(v)\text{indeg}(v), so vv is emitted strictly later. ✅
function kahn(G):
    compute indeg[v] for all v
    Q = queue of all v with indeg[v] == 0
    order = []
    while Q not empty:
        u = Q.pop()
        order.append(u)
        for each edge u -> v:
            indeg[v] -= 1
            if indeg[v] == 0: Q.push(v)
    if len(order) < |V|: report CYCLE   # leftover nodes stuck in a cycle
    return order
Figure — Topological sort — DFS-based, Kahn's algorithm (BFS-based)

Worked Example (same graph, both methods)

Graph edges: 5→0, 5→2, 4→0, 4→1, 2→3, 3→1 Vertices: 0 1 2 3 4 5

Kahn's walk-through

Indegrees: 0:2, 1:2, 2:1, 3:1, 4:0, 5:0

Step Queue (indeg 0) Pop Emit Updates
1 [4, 5] 4 4 0→1, 1→1
2 [5] 5 5 0→0✅, 2→0✅
3 [0, 2] 0 0
4 [2] 2 2 3→0✅
5 [3] 3 3 1→0✅
6 [1] 1 1

Order: 4 5 0 2 3 1Why this step? We always pulled an indegree-0 node, guaranteeing every prerequisite was already out. 6 emitted = |V| ⇒ valid DAG.

DFS walk-through (start at 5, then 4)

  • dfs(5)→dfs(0) finish 0 →dfs(2)→dfs(3)→dfs(1) finish 1, finish 3, finish 2, finish 5
  • dfs(4): 0,1 done → finish 4
  • finished list = [0,1,3,2,5,4]
  • Reverse = 4 5 2 3 1 0

Why this step? We append each node only after its descendants finished, so reversing puts roots first. (Note: different valid order from Kahn — both correct!)


Common Mistakes


Active Recall

Recall Quick self-test (cover the answers)
  • When does a topological order exist? → iff the graph is a DAG.
  • In DFS-topo, when do you record a node? → on finish, then reverse.
  • Kahn's start set? → all vertices with indegree 0.
  • Both algorithms' complexity? → O(V+E)O(V+E).
  • How does each detect a cycle? → DFS: back edge to a gray node. Kahn: emitted count <V< |V|.
Recall Feynman: explain to a 12-year-old

Imagine you have homework tasks where some must be done before others — you can't write the essay before reading the book. A topological sort lines up all tasks so you never do a later task before its required earlier one. Way 1 (DFS): dive into a task and all the tasks it leads to first; the moment you fully finish a task, drop it in a "done" pile. The pile is upside down, so flip it. Way 2 (Kahn): keep doing any task that has no leftover requirements; each time you finish one, cross it off its followers' lists — some followers now have zero requirements and become doable. If you get stuck with tasks still left, they depend on each other in a loop and can't be ordered.


Connections

  • Depth-First Search (DFS) — DFS-topo is just DFS + finish-time ordering.
  • Breadth-First Search (BFS) — Kahn's is BFS driven by indegree.
  • Directed Acyclic Graph (DAG) — the precondition for any topo order.
  • Cycle Detection in Directed Graphs — both algorithms detect cycles as a byproduct.
  • Course Schedule Problem — classic application of topological sort.
  • Shortest Path in DAG — relax edges in topological order for O(V+E)O(V+E) shortest paths.
  • Strongly Connected Components — Kosaraju uses DFS finish ordering similarly.
What is a topological ordering of a DAG?
A linear ordering of vertices such that for every directed edge u→v, u appears before v.
A topological ordering exists if and only if the graph is...?
A Directed Acyclic Graph (has no directed cycle).
In DFS-based topo sort, when is a vertex recorded?
When it FINISHES (after exploring all descendants); the final list is then reversed.
Why does reversing DFS finish order give a topo sort?
For any edge u→v in a DAG, f(u) > f(v), so decreasing finish time puts u before v.
What set of vertices initializes Kahn's queue?
All vertices with indegree 0.
In Kahn's algorithm, when do you push a neighbour onto the queue?
Exactly when its indegree, after decrementing, becomes 0.
How does Kahn's algorithm detect a cycle?
If fewer than |V| vertices are emitted, the remaining ones form a cycle.
How does DFS-based topo sort detect a cycle?
It encounters a back edge — an edge to a vertex currently on the recursion stack (gray).
Time complexity of both topological sort algorithms?
O(V + E).
Is the topological order unique?
No — any ordering respecting all edges is valid; multiple roots give multiple orders.
Why must a DAG have at least one indegree-0 vertex?
Otherwise you could follow incoming edges backward forever, which forces a repeated vertex = a cycle.

Concept Map

enables

forbids a to a

every edge u to v

solved by

solved by

append on finish then

since f of u greater than f of v

detects cycle via

removes nodes with

detects cycle if

runs in

runs in

Directed Acyclic Graph

Topological Ordering

Cycle exists

No valid order

u before v

DFS-based algorithm

Kahn's BFS algorithm

Reverse finish order

Back edge to gray node

Zero indegree

Fewer than V emitted

O of V plus E

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Topological sort ka matlab hai: ek directed graph (DAG) ke vertices ko ek line me aise arrange karna ki har edge u→v ke liye u hamesha v se pehle aaye. Socho tasks hain — pehle book padho phir essay likho. Yeh ordering sirf tabhi possible hai jab graph me koi cycle na ho (DAG ho). Cycle hone par a→b→c→a jaisi situation banti hai, jisme har cheez khud se pehle aani padti hai — impossible.

Do tareeke hain. DFS-based: node ko tab record karo jab woh finish ho (uske saare descendants explore ho gaye). Finish hone par list me daalo, phir poori list reverse kar do. Kyun? Kyunki edge u→v me u hamesha v ke baad finish hota hai, to reverse karne par u aage aa jaata hai. Yaad rakhna — entry pe record mat karo, sirf finish pe.

Kahn's algorithm (BFS-based): har vertex ka indegree (kitne edges andar aa rahe hain) count karo. Jiska indegree 0 hai uske koi prerequisite pending nahi — usko queue me daalo aur emit karo. Emit karte hi uske neighbours ka indegree 1 kam karo; jo bhi 0 ho jaaye usko queue me daalo. Repeat. Agar end me emitted count < |V| hai, matlab graph me cycle hai.

Dono O(V+E) me chalte hain. Mnemonic yaad rakho: "DFS Finishes & Flips, Kahn Counts to Zero." Real life applications — course scheduling, build dependencies, DAG me shortest path. Bahut common interview topic hai, to dono ko haath se ek chhote graph par chala kar dekho.

Go deeper — visual, from zero

Test yourself — Graphs

Connections