sp-04/src/ch/usi/inf/sp/graph/Traversal.java

58 lines
1.8 KiB
Java

package ch.usi.inf.sp.graph;
import java.util.*;
public class Traversal {
public static <G extends DiGraph<N, E>, N extends Node<E>, E extends Edge<N>>
List<N> getNodesInReversePostOrder(final DiGraph<N, E> graph, final N entryNode) {
final List<N> orderedNodes = getNodesInPostOrder(graph, entryNode);
Collections.reverse(orderedNodes);
return orderedNodes;
}
/**
* From: https://eli.thegreenplace.net/2015/directed-graph-traversal-orderings-and-applications-to-data-flow-analysis/
* <p>
* <pre>
* def postorder(graph, root):
* """Return a post-order ordering of nodes in the graph."""
* visited = set()
* order = []
* def dfs_walk(node):
* visited.add(node)
* for succ in graph.successors(node):
* if not succ in visited:
* dfs_walk(succ)
* order.append(node)
* dfs_walk(root)
* return order
* </pre>
*/
public static <G extends DiGraph<N, E>, N extends Node<E>, E extends Edge<N>>
List<N> getNodesInPostOrder(final DiGraph<N, E> graph, final N entryNode) {
final Set<N> visited = new HashSet<>();
final List<N> order = new ArrayList<>();
final Deque<N> visitStack = new ArrayDeque<>();
visitStack.push(entryNode);
mainLoop:
while (!visitStack.isEmpty()) {
final N node = visitStack.pop();
for (final E outEdge : node.getOutEdges()) {
final N successor = outEdge.getTo();
if (!visited.contains(successor)) {
visited.add(successor);
visitStack.push(node);
visitStack.push(successor);
continue mainLoop;
}
}
order.add(node);
}
return order;
}
}