Topics
Topological sorting produces linear ordering of vertices in a directed acyclic graphs (DAG). For every directed edge , vertex comes before vertex in the ordering.
Warning
Topological sort only possible for DAGs. Cycles prevent linear ordering.
Common approach uses DFS. Based on post-order traversal.
Perform DFS on graph. When DFS call for vertex v finishes (all descendants visited), prepend v to result list (or push onto stack). After visiting all nodes, list (or popped stack sequence) yields topological sort.
Correctness: Node u finishes DFS after all reachable nodes finish. Prepending/pushing reverses dependency order correctly.
graph LR
A["A"] --> B["B"]
A --> C["C"]
B --> D["D"]
C --> D
Possible topological orderings:
- A → B → C → D
- A → C → B → D
Algorithm Steps
- Initialize
visitedset and result listL(empty) - For each vertex
uin graph:- If
unot visited, callDFS(u)
- If
- Function
DFS(u):- Mark
uas visiting - For each neighbor
vofu:- If
vmarked as visiting, cycle detected (not a DAG). Stop - If
vnot visited, callDFS(v)
- If
- Mark
uas visited (finished) - Prepend
utoL
- Mark
- Return
L
Above algorithm incorporates cycle detection in directed graphs (using 3 color/state approach).
C++ Implementation (DFS)
enum class VisitState { UNVISITED, VISITING, VISITED };
bool dfs(int u,
const vector<vector<int>>& adj,
vector<VisitState>& visited,
vector<int>& result) {
visited[u] = VisitState::VISITING;
for (int v : adj[u]) {
if (visited[v] == VisitState::VISITING) {
return false; // Cycle detected
}
if (visited[v] == VisitState::UNVISITED) {
if (!dfs(v, adj, visited, result)) {
return false; // Cycle detected
}
}
}
visited[u] = VisitState::VISITED;
result.push_back(u); // Nodes added in reverse order
return true;
}
vector<int> topological_sort(const vector<vector<int>>& adj) {
vector<VisitState> visited(adj.size(), VisitState::UNVISITED);
vector<int> result;
for (int u = 0; u < adj.size(); ++u) {
if (visited[u] == VisitState::UNVISITED) {
if (!dfs(u, adj, visited, result)) {
return {}; // Cycle detected
}
}
}
reverse(result.begin(), result.end()); // Reverse to get correct order
return result;
}Application: Topological sort fundamental for dependency/ordering problems:
- Task scheduling
- Course prerequisites
- Build system dependencies
Related
- kahn’s algorithm (alternative approach using in-degrees)