@@ -18,9 +18,56 @@ import (
1818// TopologicalSort only works for directed acyclic graphs. This implementation
1919// works non-recursively and utilizes Kahn's algorithm.
2020func TopologicalSort [K comparable , T any ](g Graph [K , T ]) ([]K , error ) {
21- return StableTopologicalSort (g , func (_ , _ K ) bool {
22- return false
23- })
21+ if ! g .Traits ().IsDirected {
22+ return nil , fmt .Errorf ("topological sort cannot be computed on undirected graph" )
23+ }
24+
25+ predecessorMap , err := g .PredecessorMap ()
26+ if err != nil {
27+ return nil , fmt .Errorf ("failed to get predecessor map: %w" , err )
28+ }
29+
30+ queue := make ([]K , 0 )
31+
32+ for vertex , predecessors := range predecessorMap {
33+ if len (predecessors ) == 0 {
34+ queue = append (queue , vertex )
35+ }
36+ }
37+
38+ order := make ([]K , 0 , len (predecessorMap ))
39+ visited := make (map [K ]struct {})
40+
41+ for len (queue ) > 0 {
42+ currentVertex := queue [0 ]
43+ queue = queue [1 :]
44+
45+ if _ , ok := visited [currentVertex ]; ok {
46+ continue
47+ }
48+
49+ order = append (order , currentVertex )
50+ visited [currentVertex ] = struct {}{}
51+
52+ for vertex , predecessors := range predecessorMap {
53+ delete (predecessors , currentVertex )
54+
55+ if len (predecessors ) == 0 {
56+ queue = append (queue , vertex )
57+ }
58+ }
59+ }
60+
61+ gOrder , err := g .Order ()
62+ if err != nil {
63+ return nil , fmt .Errorf ("failed to get graph order: %w" , err )
64+ }
65+
66+ if len (order ) != gOrder {
67+ return nil , errors .New ("topological sort cannot be computed on graph with cycles" )
68+ }
69+
70+ return order , nil
2471}
2572
2673// StableTopologicalSort does the same as [TopologicalSort], but takes a function
0 commit comments