Skip to content

Commit c0f5621

Browse files
committed
Return to old implementation of TopologicalSort
1 parent 80f3d6c commit c0f5621

2 files changed

Lines changed: 55 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project
66
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.22.1] - 2023-06-05
9+
10+
### Fixed
11+
* Fixed `TopologicalSort` to retain its original performance.
12+
813
## [0.22.0] - 2023-05-24
914

1015
### Added

dag.go

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,56 @@ import (
1818
// TopologicalSort only works for directed acyclic graphs. This implementation
1919
// works non-recursively and utilizes Kahn's algorithm.
2020
func 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

Comments
 (0)