Skip to content

Commit

Permalink
Return to old implementation of TopologicalSort
Browse files Browse the repository at this point in the history
  • Loading branch information
dominikbraun committed Jun 5, 2023
1 parent 80f3d6c commit c0f5621
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 3 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.22.1] - 2023-06-05

### Fixed
* Fixed `TopologicalSort` to retain its original performance.

## [0.22.0] - 2023-05-24

### Added
Expand Down
53 changes: 50 additions & 3 deletions dag.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,56 @@ import (
// TopologicalSort only works for directed acyclic graphs. This implementation
// works non-recursively and utilizes Kahn's algorithm.
func TopologicalSort[K comparable, T any](g Graph[K, T]) ([]K, error) {
return StableTopologicalSort(g, func(_, _ K) bool {
return false
})
if !g.Traits().IsDirected {
return nil, fmt.Errorf("topological sort cannot be computed on undirected graph")
}

predecessorMap, err := g.PredecessorMap()
if err != nil {
return nil, fmt.Errorf("failed to get predecessor map: %w", err)
}

queue := make([]K, 0)

for vertex, predecessors := range predecessorMap {
if len(predecessors) == 0 {
queue = append(queue, vertex)
}
}

order := make([]K, 0, len(predecessorMap))
visited := make(map[K]struct{})

for len(queue) > 0 {
currentVertex := queue[0]
queue = queue[1:]

if _, ok := visited[currentVertex]; ok {
continue
}

order = append(order, currentVertex)
visited[currentVertex] = struct{}{}

for vertex, predecessors := range predecessorMap {
delete(predecessors, currentVertex)

if len(predecessors) == 0 {
queue = append(queue, vertex)
}
}
}

gOrder, err := g.Order()
if err != nil {
return nil, fmt.Errorf("failed to get graph order: %w", err)
}

if len(order) != gOrder {
return nil, errors.New("topological sort cannot be computed on graph with cycles")
}

return order, nil
}

// StableTopologicalSort does the same as [TopologicalSort], but takes a function
Expand Down

0 comments on commit c0f5621

Please sign in to comment.