package org.core4j;
import java.util.Stack;
public class DepthFirstIterator<T> extends ReadOnlyIterator<T> {
private final Func1<T, Enumerable<T>> childrenFn;
private final Stack<T> stack = new Stack<T>();
public DepthFirstIterator(T startingNode, Func1<T, Enumerable<T>> childrenFn) {
this.childrenFn = childrenFn;
this.stack.add(startingNode);
}
@Override
protected IterationResult<T> advance() throws Exception {
// first child
for (T child : childrenFn.apply(stack.peek())) {
stack.push(child);
return IterationResult.next(child);
}
// no children
while (stack.size() > 1) {
T currentNode = stack.pop();
// look for next sibling
boolean foundSelf = false;
for (T sibling : childrenFn.apply(stack.peek())) {
if (foundSelf) {
stack.push(sibling);
return IterationResult.next(sibling);
}
if (sibling.equals(currentNode)) {
foundSelf = true;
}
}
// no sibling found, move up and try again
}
return IterationResult.done();
}
}