Skip to main content

Topological Sort

pari
EditReport

The Topological Sort is a linear ordering of vertices in a Directed Acyclic Graph (DAG) such that for every directed edge u โ†’ v, vertex u appears before vertex v in the ordering.

It is commonly used when tasks have dependencies and must be performed in a specific sequence.

Key Feature

Topological Sort is only possible in a Directed Acyclic Graph (DAG). If the graph contains a cycle, a valid topological ordering does not exist.


How It Worksโ€‹

The algorithm is commonly implemented using Kahn's Algorithm (BFS) or Depth-First Search (DFS).

The most popular approach is Kahn's Algorithm, which repeatedly selects nodes with zero incoming edges.

Stepsโ€‹

  1. Calculate the in-degree of every vertex.
  2. Add all vertices with in-degree 0 to a queue.
  3. Remove a vertex from the queue and add it to the result.
  4. Decrease the in-degree of all its adjacent vertices.
  5. If any adjacent vertex becomes 0, add it to the queue.
  6. Repeat until the queue becomes empty.
  7. If the number of processed vertices is less than the total number of vertices, the graph contains a cycle.

Complexity Analysisโ€‹

MetricValue
Time ComplexityO(V + E)
Space ComplexityO(V)

Where:

  • V = Number of Vertices
  • E = Number of Edges

Implementationsโ€‹

Pythonโ€‹

from collections import deque

def topological_sort(graph, vertices):
indegree = [0] * vertices

for u in graph:
for v in graph[u]:
indegree[v] += 1

queue = deque()

for i in range(vertices):
if indegree[i] == 0:
queue.append(i)

result = []

while queue:
node = queue.popleft()
result.append(node)

for neighbor in graph.get(node, []):
indegree[neighbor] -= 1

if indegree[neighbor] == 0:
queue.append(neighbor)

return result if len(result) == vertices else []


graph = {
0: [1, 2],
1: [3],
2: [3]
}

print(topological_sort(graph, 4))

Javaโ€‹

import java.util.*;

public class TopologicalSort {

public static void topologicalSort(List<List<Integer>> graph, int V) {
int[] indegree = new int[V];

for (int i = 0; i < V; i++) {
for (int neighbor : graph.get(i)) {
indegree[neighbor]++;
}
}

Queue<Integer> queue = new LinkedList<>();

for (int i = 0; i < V; i++) {
if (indegree[i] == 0) {
queue.add(i);
}
}

int count = 0;

while (!queue.isEmpty()) {
int node = queue.poll();
System.out.print(node + " ");
count++;

for (int neighbor : graph.get(node)) {
indegree[neighbor]--;

if (indegree[neighbor] == 0) {
queue.add(neighbor);
}
}
}

if (count != V) {
System.out.println("\nCycle detected. Topological ordering not possible.");
}
}
}

C++โ€‹

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

vector<int> topologicalSort(int V, vector<vector<int>>& graph) {
vector<int> indegree(V, 0);

for (int i = 0; i < V; i++) {
for (int neighbor : graph[i]) {
indegree[neighbor]++;
}
}

queue<int> q;

for (int i = 0; i < V; i++) {
if (indegree[i] == 0)
q.push(i);
}

vector<int> result;

while (!q.empty()) {
int node = q.front();
q.pop();

result.push_back(node);

for (int neighbor : graph[node]) {
indegree[neighbor]--;

if (indegree[neighbor] == 0)
q.push(neighbor);
}
}

return result.size() == V ? result : vector<int>();
}

JavaScriptโ€‹

function topologicalSort(graph, V) {
const indegree = new Array(V).fill(0);

for (let u = 0; u < V; u++) {
for (const v of graph[u]) {
indegree[v]++;
}
}

const queue = [];

for (let i = 0; i < V; i++) {
if (indegree[i] === 0) {
queue.push(i);
}
}

const result = [];

while (queue.length) {
const node = queue.shift();
result.push(node);

for (const neighbor of graph[node]) {
indegree[neighbor]--;

if (indegree[neighbor] === 0) {
queue.push(neighbor);
}
}
}

return result.length === V ? result : [];
}

Real-World Use Casesโ€‹

  • Course Scheduling โ€” Determine the order of courses based on prerequisites.
  • Build Systems โ€” Compile source files in dependency order.
  • Task Scheduling โ€” Execute dependent tasks in the correct sequence.
  • Package Management โ€” Install software packages while respecting dependencies.
  • Project Planning โ€” Organize workflows where certain tasks must be completed before others.
Telemetry Integration

Completed working through this block? Sync progress to workspace.