I am trying to implement the iterator class for optional binary trees in Python. After the iterator is built with the root of the node tree, its next() function can be called again to traverse the tree in depth order (for example, this order ), finally returning None when there are no nodes.
Here is the base Node class for a tree:
class Node(object): def __init__(self, title, children=None): self.title = title self.children = children or [] self.visited = False def __str__(self): return self.title
As you can see above, I introduced the visited property for nodes for my first approach, since I did not see the path around it. With this extra state, the Iterator class looks like this:
class Iterator(object): def __init__(self, root): self.stack = [] self.current = root def next(self): if self.current is None: return None self.stack.append(self.current) self.current.visited = True
This is good and good, but I want to get rid of the need for the visited property without resorting to recursion or other changes to the Node class.
All the state I need should take care of the iterator, but I don't understand how this can be done. Saving the visited list for the whole tree is non-scalable and out of the question, so there should be a smart way to use the stack.
What bothers me especially is because the next() function certainly returns, how can I remember where I was without labeling or using redundant storage? Intuitively, I think about iterating over children, but this logic is interrupted / forgotten when the next() function returns!
UPDATE - here is a little test:
tree = Node( 'A', [ Node('B', [ Node('C', [ Node('D') ]), Node('E'), ]), Node('F'), Node('G'), ]) iter = Iterator(tree) out = object() while out: out = iter.next() print out