| 867 | * @category transformations |
| 868 | */ |
| 869 | export const reverse = <N, E, T extends Kind = "directed">( |
| 870 | mutable: MutableGraph<N, E, T> |
| 871 | ): void => { |
| 872 | // Reverse all edges by swapping source and target |
| 873 | for (const [index, edgeData] of mutable.edges) { |
| 874 | mutable.edges.set(index, { |
| 875 | source: edgeData.target, |
| 876 | target: edgeData.source, |
| 877 | data: edgeData.data |
| 878 | }) |
| 879 | } |
| 880 | |
| 881 | // Clear and rebuild adjacency lists with reversed directions |
| 882 | mutable.adjacency.clear() |
| 883 | mutable.reverseAdjacency.clear() |
| 884 | |
| 885 | // Rebuild adjacency lists with reversed directions |
| 886 | for (const [edgeIndex, edgeData] of mutable.edges) { |
| 887 | // Add to forward adjacency (source -> target) |
| 888 | const sourceEdges = mutable.adjacency.get(edgeData.source) || [] |
| 889 | sourceEdges.push(edgeIndex) |
| 890 | mutable.adjacency.set(edgeData.source, sourceEdges) |
| 891 | |
| 892 | // Add to reverse adjacency (target <- source) |
| 893 | const targetEdges = mutable.reverseAdjacency.get(edgeData.target) || [] |
| 894 | targetEdges.push(edgeIndex) |
| 895 | mutable.reverseAdjacency.set(edgeData.target, targetEdges) |
| 896 | } |
| 897 | |
| 898 | // Invalidate cycle flag since edge directions changed |
| 899 | mutable.isAcyclic = Option.none() |
| 900 | } |
| 901 | |
| 902 | /** |
| 903 | * Filters and optionally transforms nodes in a mutable graph using a predicate function. |