package graphutils;
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
public class PostorderIterator<V, E extends Edge<V>> implements Iterator<V>
{
private AbstractGraph<V, E> graph;
Deque<V> remainingNodes;
List<V> visitedNodes;
public PostorderIterator(AbstractGraph<V, E> graph, V root)
{
this.graph = graph;
this.remainingNodes = new LinkedList<V>();
this.visitedNodes = new LinkedList<V>();
this.remainingNodes.push(root);
}
@Override
public boolean hasNext()
{
return !remainingNodes.isEmpty();
}
@Override
public V next()
{
while (hasNext())
{
V root = remainingNodes.peek();
// visit root
if (!visitedNodes.contains(root))
{
visitedNodes.add(root);
}
// predecessors first if any
if (graph.outDegree(root) > 0)
{
for (E edge : graph.outgoingEdges(root))
{
if (!visitedNodes.contains(edge.getDestination()))
{
remainingNodes.push(edge.getDestination());
// depth first
break;
}
}
}
// No adjacent vertices or all adjacent vertices already visited
// This means the current subtree rooted at the current node is
// done and we can go back to its root.
if (remainingNodes.peek().equals(root))
{
return remainingNodes.poll();
}
}
throw new NoSuchElementException();
}
@Override
public void remove()
{
throw new UnsupportedOperationException("Operation not allowed");
}
}