Instead of calling self.left/right.
in
_order_list()
you call self.left/right.
pre
_order_list()
.
To accomplish what you want to do, the generator function may be better (less memory and more pythonic) than accumulating values ββin a list:
class Tree(object): ... def in_order(self): if self.left is not None: for value in self.left.in_order(): yield value yield self.value
This way you do not need to create a list if you only want to iterate over the values:
for value in tree.in_order(): ...
The algorithm works as follows: the generator first descends recursively along the left branch of each node until it reaches one without the left sub-node. Then it gives the current value of node. After that, he does the same on the right under the node, but starts with the current node, and not with the root of the node. If we assume that there are no cycles in the tree and there are no infinite branches, then there will definitely be leaf nodes, i.e. Nodes without left or right sub-node. IOW, for which both basic options have been achieved ( self.left/right is None
). Therefore, recursive calls return, I hope, before we go out of memory or reach the stack limit.
The loop over self.left/right.in_order()
necessary due to the fact that the returned call in_order()
is a generator, therefore the name generator function. The returned generator must be somehow exhausted, for example. through the loop. In the body of the loop, we return the values ββone level, where they return again until they reach the top level. There we use the values.
If you want to get the nodes yourself, and not just your value fields, you can do this as follows:
class Tree(object): ... def in_order(self): if self.left is not None: for node in self.left.in_order(): yield node yield self
You probably want to do this because you can not only access the values ββof the nodes:
for node in tree.in_order(): do_something_with(node.value)
but also you can do whatever you want with nodes:
for node in tree.in_order(): whatever(node.some_other_attribute)