Skip to content

Commit 5d9df4c

Browse files
committed
doc: added doc for graph/kahn.go
1 parent ab8845e commit 5d9df4c

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

graph/kahn.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,33 @@
1+
// Kahn's algorithm computes a topological ordering of a directed acyclic graph (DAG).
2+
// Time Complexity: O(V + E)
3+
// Space Complexity: O(V + E)
4+
// Reference: https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm
5+
// see graph.go, topological.go, kahn_test.go
6+
17
package graph
28

9+
// Kahn's algorithm computes a topological ordering of a directed acyclic graph (DAG).
10+
// `n` is the number of vertices,
11+
// `dependencies` is a list of directed edges, where each pair [a, b] represents
12+
// a directed edge from a to b (i.e. b depends on a).
13+
// Vertices are assumed to be labelled 0, 1, ..., n-1.
14+
// If the graph is not a DAG, the function returns nil.
315
func Kahn(n int, dependencies [][]int) []int {
416
g := Graph{vertices: n, Directed: true}
17+
// track the in-degree (number of incoming edges) of each vertex
518
inDegree := make([]int, n)
619

20+
// populate g with edges, increase the in-degree counts accordingly
721
for _, d := range dependencies {
22+
// make sure we don't add the same edge twice
823
if _, ok := g.edges[d[0]][d[1]]; !ok {
924
g.AddEdge(d[0], d[1])
1025
inDegree[d[1]]++
1126
}
1227
}
1328

29+
// queue holds all vertices with in-degree 0
30+
// these vertices have no dependency and thus can be ordered first
1431
queue := make([]int, 0, n)
1532

1633
for i := 0; i < n; i++ {
@@ -19,12 +36,20 @@ func Kahn(n int, dependencies [][]int) []int {
1936
}
2037
}
2138

39+
// order holds a valid topological order
2240
order := make([]int, 0, n)
2341

42+
// process the dependency-free vertices
43+
// every time we process a vertex, we "remove" it from the graph
2444
for len(queue) > 0 {
45+
// pop the first vertex from the queue
2546
vtx := queue[0]
2647
queue = queue[1:]
48+
// add the vertex to the topological order
2749
order = append(order, vtx)
50+
// "remove" all the edges coming out of this vertex
51+
// every time we remove an edge, the corresponding in-degree reduces by 1
52+
// if all dependencies on a vertex is removed, enqueue the vertex
2853
for neighbour := range g.edges[vtx] {
2954
inDegree[neighbour]--
3055
if inDegree[neighbour] == 0 {
@@ -33,6 +58,7 @@ func Kahn(n int, dependencies [][]int) []int {
3358
}
3459
}
3560

61+
// if the graph is a DAG, order should contain all the certices
3662
if len(order) != n {
3763
return nil
3864
}

0 commit comments

Comments
 (0)