-
Notifications
You must be signed in to change notification settings - Fork 77
/
Copy pathtopological_sort.go
100 lines (91 loc) · 1.97 KB
/
topological_sort.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package goraph
// TopologicalSort does topological sort(ordering) with DFS.
// It returns true if the graph is a DAG (no cycle, with a topological sort).
// False if the graph is not a DAG (cycle, with no topological sort).
//
// 0. TopologicalSort(G)
// 1.
// 2. L = Empty list that will contain the sorted nodes
// 3. isDAG = true
// 4.
// 5. for each vertex v in G:
// 6.
// 7. if v.color == "white":
// 8.
// 9. topologicalSortVisit(v, L, isDAG)
// 10.
// 11.
// 12.
// 13.
// 14. topologicalSortVisit(v, L, isDAG)
// 15.
// 16. if v.color == "gray":
// 17. isDAG = false
// 18. return
// 19.
// 20. if v.color == "white":
// 21.
// 22. v.color = "gray":
// 23.
// 24. for each child vertex w of v:
// 25. topologicalSortVisit(w, L, isDAG)
// 26.
// 27. v.color = "black"
// 28. L.push_front(v)
//
func TopologicalSort(g Graph) ([]ID, bool) {
// L = Empty list that will contain the sorted nodes
L := []ID{}
isDAG := true
color := make(map[ID]string)
for v := range g.GetNodes() {
color[v] = "white"
}
// for each vertex v in G:
for v := range g.GetNodes() {
// if v.color == "white":
if color[v] == "white" {
// topologicalSortVisit(v, L, isDAG)
topologicalSortVisit(g, v, &L, &isDAG, &color)
}
}
reverse(L)
return L, isDAG
}
func topologicalSortVisit(
g Graph,
id ID,
L *[]ID,
isDAG *bool,
color *map[ID]string,
) {
// if v.color == "gray":
if (*color)[id] == "gray" {
// isDAG = false
*isDAG = false
return
}
// if v.color == "white":
if (*color)[id] == "white" {
// v.color = "gray":
(*color)[id] = "gray"
// for each child vertex w of v:
cmap, err := g.GetTargets(id)
if err != nil {
panic(err)
}
for w := range cmap {
// topologicalSortVisit(w, L, isDAG)
topologicalSortVisit(g, w, L, isDAG, color)
}
// v.color = "black"
(*color)[id] = "black"
// L.append(v)
*L = append(*L, id)
}
}
func reverse(a []ID) {
for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
a[i], a[j] = a[j], a[i]
}
}