transpose.go (1203B)
1 // Copyright 2026 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package graph 6 7 import ( 8 "iter" 9 "slices" 10 ) 11 12 type transpose[NodeID comparable] struct { 13 Graph Graph[NodeID] 14 preds map[NodeID][]NodeID 15 } 16 17 // transpose returns a graph like g but with all edges reversed. Node IDs are 18 // identical to the underlying graph. 19 // 20 // Transpose preserves compactness. 21 func Transpose[NodeID comparable](g Graph[NodeID]) Graph[NodeID] { 22 if g, ok := g.(transpose[NodeID]); ok { 23 // Transpose(Transpose(g)) == g 24 return g.Graph 25 } 26 27 preds := make(map[NodeID][]NodeID) 28 for nid := range g.Nodes() { 29 for succ := range g.Out(nid) { 30 preds[succ] = append(preds[succ], nid) 31 } 32 } 33 return transpose[NodeID]{g, preds} 34 } 35 36 func (t transpose[NodeID]) NumNodes() int { 37 return len(t.preds) 38 } 39 40 func (t transpose[NodeID]) Nodes() iter.Seq[NodeID] { 41 return t.Graph.Nodes() 42 } 43 44 func (t transpose[NodeID]) Out(n NodeID) iter.Seq[NodeID] { 45 return slices.Values(t.preds[n]) 46 } 47 48 //lint:ignore U1000 False positive in Staticcheck 2026.1 and older. 49 func (t transpose[NodeID]) unwrapPreservingNodes() Graph[NodeID] { 50 return t.Graph 51 }