The In-order Iterator
Here is a binary search tree that implements Iterable<T>. Its iterator returns the tree’s values in ascending order, one value per call to next. next throws NoSuchElementException when there are no values left. The iterator is an inner class, so it can read root. Its only field is a stack of nodes, and it does not use recursion.
public class BinarySearchTree<T extends Comparable<T>>
implements Iterable<T> {
private Node<T> root;
private static class Node<T> {
T value;
Node<T> left;
Node<T> right;
Node(T value) {
this.value = value;
}
}
@Override
public Iterator<T> iterator() {
return new BinarySearchTreeIterator();
}
private class BinarySearchTreeIterator implements Iterator<T> {
private Stack<Node<T>> stack = new LinkedStack<>();
BinarySearchTreeIterator() {
// TODO
}
@Override
public boolean hasNext() {
// TODO
}
@Override
public T next() {
// TODO
}
}
}
The stack follows this interface, and LinkedStack implements it:
public interface Stack<T> {
void push(T item); // adds item to the top
void pop(); // removes the top item; throws if empty
T top(); // returns the top item; throws if empty
boolean isEmpty();
}
Solution
private class BinarySearchTreeIterator implements Iterator<T> {
private Stack<Node<T>> stack = new LinkedStack<>();
BinarySearchTreeIterator() {
pushLeftSpine(root);
}
private void pushLeftSpine(Node<T> node) {
while (node != null) {
stack.push(node);
node = node.left;
}
}
@Override
public boolean hasNext() {
return !stack.isEmpty();
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
Node<T> node = stack.top();
stack.pop();
T value = node.value;
pushLeftSpine(node.right);
return value;
}
}
Solution
constructor stack: 17 33
next returns 17 stack: 25 33
next returns 25 stack: 33
next returns 33 stack: 40 46 58
next returns 40 stack: 46 58
next returns 46 stack: 58
next returns 58 stack: 71
next returns 71 stack: (empty)
Solution
The constructor is , hasNext is , and next is in the worst case. Over a full traversal, every node is pushed once and popped once, so the calls to next do work in total. That makes next amortized .
Solution
. The nodes on the stack all lie on one path down from the root, so the stack holds at most nodes.