It is possible to traverse a mutable ordered tree iteratively, by recording the node's parent in the branches you take, and knowing the direction you approach a node from ( down, or up from the left or right, which the ordered property of the tree lets you test ):
template <typename T, typename R>
void in_order ( BSTNode<T>* root, R (*routine)(T) ) {
typedef BSTNode<T>* Node;
Node current = root;
Node parent = 0;
bool going_down = true;
while ( current ) {
Node next = 0;
if ( going_down ) {
if ( current -> leftChild ) {
// navigate down the left, swapping prev with the path taken
Node next_child = current -> leftChild;
current -> leftChild = parent;
parent = current;
current = next_child;
} else if ( current -> rightChild ) {
// navigate down the right, swapping prev with the path taken
Node next_child = current -> rightChild;
current -> rightChild = parent;
parent = current;
current = next_child;
} else {
// leaf
routine ( current -> data );
going_down = false;
}
} else {
// moving up to parent
if ( parent ) {
Node next_parent = 0;
// came from the left branch
if ( parent -> data > current -> data ) {
// visit parent after left branch
routine ( parent -> data );
// repair parent
next_parent = parent -> leftChild;
parent -> leftChild = current;
// traverse right if possible
if ( parent -> rightChild ) {
going_down = true;
// navigate down the right, swapping prev with the path taken
Node next_child = parent -> rightChild;
parent -> rightChild = next_parent;
//parent = current;
current = next_child;
continue;
}
} else {
// came from the right branch
next_parent = parent -> rightChild;
parent -> rightChild = current;
}
current = parent;
parent = next_parent;
} else {
break;
}
}
}
}
If rather than storing the children, you store the XOR of the parent and child, then you can get the next node in whatever direction you approach from without having to mutate the tree.
I don't know of anything with automatically transforms non-tail recursive functions into such code. I do know of environments where the call stack is allocated on the heap, which transparently avoid a stack overflow in cases where you can't perform such mutations and have a fixed small stack size. Usually recording the state on a stack takes less space that the call stack, as you're selecting only the essential local state to record, and are not recording return addresses or any caller-save registers ( if you used a functor rather than a function pointer, then it's more likely that the compiler might be able to inline routine
and so not save the caller save registers in the simple recursive case, so reducing the amount of stack required for each recursion. YMMV ).
Since you're using templates you should only need to do the traversal code once, and combine it with strategy templates to switch between pre, post and inorder, or whatever other iteration modes you want.