A good approach is to use a stack to manage sequencing, which is sort of done for you if you use a recursive traversal (instead of trying to build an Iterator at all) as described in SteveL's answer.
As you want to start from the left, you first load onto the stack the root node and its leftmost children in the proper order (push while going down to the left from the root).
Always pop the next from the top of the stack, and push its right child (if any) and all its leftmost children before returning the one you just popped, so that they're next in line.
By this approach, the top of the stack will always be the next to return, and when the stack is empty, there's no more...
In code:
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Stack;
public class TreeNodeInOrderIterator<T> implements Iterator<T> {
private final Stack<TreeNode<T>> stack;
public TreeNodeInOrderIterator(TreeNode<T> root) {
this.stack = new Stack<TreeNode<T>>();
pushLeftChildren(root);
}
@Override
public boolean hasNext() {
return !stack.isEmpty();
}
@Override
public T next() {
if (!hasNext())
throw new NoSuchElementException();
TreeNode<T> top = stack.pop();
pushLeftChildren(top.right);
return top.val;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
private void pushLeftChildren(TreeNode<T> cur) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
}
}
In this code, TreeNode
is defined by
public class TreeNode<T> {
T val;
TreeNode<T> left;
TreeNode<T> right;
TreeNode(T x) { val = x; }
}
If you want to have each node also know its parent, that's ok, but all the traversal is by using what's on the stack and adding to the stack using the left
and right
child links.