This commit is contained in:
parent
f0fd3f8df1
commit
401f5c3848
41
container/graph/topo.go
Normal file
41
container/graph/topo.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package sort
|
||||||
|
|
||||||
|
// Node is a generic interface representing a graph node.
|
||||||
|
type Node[T any] interface {
|
||||||
|
// Value returns the value of the node.
|
||||||
|
Value() T
|
||||||
|
// Adjacencies returns a slice of nodes adjacent to this node
|
||||||
|
Adjacencies() []Node[T]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Topo performs a topological sort on a slice of nodes in place.
|
||||||
|
func TopoSort[T any](nodes []Node[T]) {
|
||||||
|
v := make(map[Node[T]]bool)
|
||||||
|
pos := 0
|
||||||
|
var dfs func(Node[T])
|
||||||
|
dfs = func(n Node[T]) {
|
||||||
|
v[n] = true
|
||||||
|
for _, e := range n.Adjacencies() {
|
||||||
|
if !v[e] {
|
||||||
|
dfs(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nodes[pos] = n
|
||||||
|
pos++
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, n := range nodes {
|
||||||
|
if !v[n] {
|
||||||
|
dfs(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RTopoSort performs a reverse topological sort on a slice of nodes in place.
|
||||||
|
func RTopoSort[T any](nodes []Node[T]) {
|
||||||
|
TopoSort(nodes)
|
||||||
|
|
||||||
|
for i, j := 0, len(nodes)-1; i < j; i, j = i+1, j-1 {
|
||||||
|
nodes[i], nodes[j] = nodes[j], nodes[i]
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user