← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Topological Sort

algorithms PHP 7.4+ Intermediate

Also Known As

topo sort dependency ordering DAG ordering

TL;DR

An ordering of nodes in a directed acyclic graph (DAG) such that for every directed edge u→v, node u appears before v in the ordering.

Explanation

Topological sort is only possible on directed acyclic graphs (DAGs) — any cycle makes a valid ordering impossible. Two common algorithms: Kahn's algorithm uses in-degree counts and a queue (BFS-based), and DFS-based sort uses recursive post-order traversal. Both run in O(V + E). The result is not unique — many valid orderings may exist. Real-world applications are everywhere: package/dependency managers (Composer, npm) use it to determine installation order, build systems (Make, Gradle) use it for task scheduling, course prerequisite systems, and database migration runners rely on it to apply schema changes in the right order.

Diagram

flowchart LR
    subgraph DAG Input
        A --> B
        A --> C
        B --> D
        C --> D
        D --> E
    end
    subgraph Kahn Step-by-Step
        K1[Start: A has in-degree 0] --> K2[Process A<br/>reduce B and C]
        K2 --> K3[Process B and C<br/>reduce D]
        K3 --> K4[Process D<br/>reduce E]
        K4 --> K5[Process E<br/>done]
    end
    RESULT[Order: A - B - C - D - E]
style RESULT fill:#238636,color:#fff
style K1 fill:#1f6feb,color:#fff

Common Misconception

Topological sort works on any directed graph — it only works on DAGs. If a cycle exists (A→B→C→A) there is no valid topological ordering, and Kahn's algorithm will detect this because not all nodes will be processed (remaining in-degrees never reach zero).

Why It Matters

Any time you have tasks, packages, or migrations with dependencies, you need topological sort under the hood. Implementing a dependency resolver or build system without understanding it leads to brittle ad-hoc ordering logic that breaks on edge cases.

Common Mistakes

  • Not detecting cycles — silently returning a partial ordering when a cycle exists instead of throwing an error.
  • Using topological sort on an undirected graph — the concept only applies to directed edges.
  • Assuming the output order is unique — many valid orderings exist; tests should not depend on a specific one.
  • Reinventing it manually with nested loops instead of using Kahn's or DFS — O(V²) instead of O(V+E).

Code Examples

💡 Note
Kahn's naturally detects cycles — if `count($order) !== count($graph)` after processing, a cycle prevented some nodes from ever reaching in-degree zero.
✗ Vulnerable
// Naive: repeatedly scan for nodes with no unresolved deps — O(V²):
function topoNaive(array $deps): array {
    $resolved = [];
    while (count($resolved) < count($deps)) {
        $progress = false;
        foreach ($deps as $node => $nodeDeps) {
            if (!in_array($node, $resolved) &&
                empty(array_diff($nodeDeps, $resolved))) {
                $resolved[] = $node;
                $progress = true;
            }
        }
        if (!$progress) throw new RuntimeException('Cycle detected');
    }
    return $resolved;
}
✓ Fixed
// Kahn's algorithm — O(V+E) with cycle detection:
function topologicalSort(array $graph): array {
    $inDegree = array_fill_keys(array_keys($graph), 0);
    foreach ($graph as $neighbours) {
        foreach ($neighbours as $v) $inDegree[$v]++;
    }
    $queue = array_keys(array_filter($inDegree, fn($d) => $d === 0));
    $order = [];
    while ($queue) {
        $u = array_shift($queue);
        $order[] = $u;
        foreach ($graph[$u] as $v) {
            if (--$inDegree[$v] === 0) $queue[] = $v;
        }
    }
    if (count($order) !== count($graph)) {
        throw new RuntimeException('Graph has a cycle — topological sort impossible');
    }
    return $order;
}

// Usage: ['a' => ['b','c'], 'b' => ['d'], 'c' => ['d'], 'd' => []]
// Returns: ['a', 'b', 'c', 'd'] or ['a', 'c', 'b', 'd']

Added 24 Mar 2026
Views 25
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T
No pings yet today
No pings yesterday
Amazonbot 8 Perplexity 5 Unknown AI 2 Google 2 Ahrefs 2 ChatGPT 1
crawler 20
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Medium
⚡ Quick Fix
Use Kahn's algorithm with an in-degree map and queue — O(V+E), detects cycles automatically
📦 Applies To
PHP 7.4+ web cli
🔗 Prerequisites
🔍 Detection Hints
Nested loops resolving dependency order; repeated array_diff or in_array inside while loop
Auto-detectable: ✗ No
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Medium Context: Function Tests: Update

✓ schema.org compliant