Topological Sort Using Kahn's Algorithm BFS in DSA C - Time & Space Complexity
We want to understand how the time needed to perform topological sort using Kahn's Algorithm grows as the graph size increases.
Specifically, how the number of nodes and edges affects the work done.
Analyze the time complexity of the following code snippet.
void kahnTopologicalSort(int V, vector<int> adj[]) {
vector<int> indegree(V, 0);
for (int i = 0; i < V; i++) {
for (int node : adj[i]) {
indegree[node]++;
}
}
queue<int> q;
for (int i = 0; i < V; i++) {
if (indegree[i] == 0) q.push(i);
}
while (!q.empty()) {
int u = q.front(); q.pop();
// process u
for (int node : adj[u]) {
indegree[node]--;
if (indegree[node] == 0) q.push(node);
}
}
}
This code performs a topological sort on a graph with V nodes using Kahn's BFS algorithm.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Traversing all edges and nodes in the graph.
- How many times: Each edge is visited once when counting indegrees and once when processing nodes from the queue.
The work grows roughly with the number of nodes plus the number of edges.
| Input Size (V, E) | Approx. Operations |
|---|---|
| V=10, E=15 | About 25 operations (10 nodes + 15 edges) |
| V=100, E=200 | About 300 operations (100 + 200) |
| V=1000, E=5000 | About 6000 operations (1000 + 5000) |
Pattern observation: The operations increase linearly with the sum of nodes and edges.
Time Complexity: O(V + E)
This means the time grows linearly with the total number of nodes and edges in the graph.
[X] Wrong: "The algorithm runs in O(V²) because of nested loops."
[OK] Correct: The inner loops do not run for all pairs; they run once per edge, so total work depends on edges, not all pairs of nodes.
Understanding this time complexity helps you explain how graph algorithms scale and why Kahn's method is efficient for topological sorting.
"What if the graph was represented using an adjacency matrix instead of adjacency lists? How would the time complexity change?"
Practice
Solution
Step 1: Understand Kahn's Algorithm goal
Kahn's Algorithm is designed to produce a linear ordering of vertices in a Directed Acyclic Graph (DAG) such that for every directed edge u -> v, u comes before v in the ordering.Step 2: Compare with other graph algorithms
Other options like shortest path, cycle detection, and minimum spanning tree solve different problems unrelated to topological sorting.Final Answer:
To find a topological ordering of a Directed Acyclic Graph (DAG) -> Option BQuick Check:
Topological sort = Kahn's Algorithm purpose [OK]
- Confusing topological sort with shortest path
- Thinking it detects cycles in undirected graphs
- Mixing it up with minimum spanning tree algorithms
Solution
Step 1: Identify the data structure for zero in-degree nodes
Kahn's Algorithm uses a queue to process nodes with zero incoming edges in a first-in-first-out manner, ensuring correct topological order.Step 2: Why not other data structures?
A stack would reverse the order, a priority queue is not necessary for basic Kahn's Algorithm, and a hash map stores key-value pairs, not order.Final Answer:
Queue -> Option CQuick Check:
Zero in-degree nodes stored in queue [OK]
- Using stack instead of queue
- Confusing priority queue with normal queue
- Thinking hash map manages order
Solution
Step 1: Calculate in-degree of each node
Nodes: 0(in-degree 2),1(2),2(1),3(1),4(0),5(0). Start with nodes 4 and 5 in queue (pushed in ascending order: queue [4,5]).Step 2: Process nodes in queue and update in-degree
Pop 4: output [4], reduce 0->1, 1->1. Queue: [5]
Pop 5: output [4,5], reduce 2->0 (push 2), 0->0 (push 0). Queue: [2,0]
Pop 2: output [4,5,2], reduce 3->0 (push 3). Queue: [0,3]
Pop 0: output [4,5,2,0], no neighbors. Queue: [3]
Pop 3: output [4,5,2,0,3], reduce 1->0 (push 1). Queue: [1]
Pop 1: output [4,5,2,0,3,1]. All nodes processed.Final Answer:
[4, 5, 2, 0, 3, 1] -> Option AQuick Check:
Topological order = [4, 5, 2, 0, 3, 1] [OK]
- Not updating in-degree after removing nodes
- Wrong initial zero in-degree nodes
- Mixing order of nodes in queue
int indegree[V] = {0};
for (int i = 0; i < V; i++) {
for (int j = 0; j < adj[i].size(); j++) {
indegree[adj[i][j]]++;
}
}
queue<int> q;
for (int i = 0; i < V; i++) {
if (indegree[i] == 0) q.push(i);
}
while (!q.empty()) {
int u = q.front(); q.pop();
cout << u << " ";
for (int v : adj[u]) {
indegree[v]--;
if (indegree[v] == 0) q.push(v);
}
}Solution
Step 1: Check indegree initialization
Indegree array is initialized to zero for all vertices correctly using {0} syntax.Step 2: Verify adjacency list and loops
Loops correctly calculate indegree, push zero indegree nodes, and process queue with BFS logic.Final Answer:
No error, the code is correct -> Option AQuick Check:
Code matches Kahn's Algorithm steps [OK]
- Forgetting to initialize indegree array
- Incorrect adjacency list declaration
- Missing zero indegree node insertion
Solution
Step 1: Identify cycle in the graph
The edges 3->4, 4->5, and 5->3 form a cycle (3->4->5->3), so the graph is not a DAG.Step 2: Understand Kahn's Algorithm behavior on cycles
Kahn's Algorithm fails to process all nodes if a cycle exists because some nodes never reach zero in-degree, indicating no valid topological order.Final Answer:
The graph contains a cycle, so no topological order -> Option DQuick Check:
Cycle detected = no topological order [OK]
- Assuming topological order exists despite cycle
- Thinking disconnected graph always causes failure
- Believing algorithm runs infinitely on cycle
Ready to prove it?
Pass the test and this pattern moves unknown
