58 lines
1.8 KiB
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;
|
|
}
|
|
}
|