Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using generators to perform an inorder tree traversal on a BST

So given the following:

def inorder(t):
    if t:
        inorder(t.left)
        yield t.key
        inorder(t.right)

x = [ n for n in inorder(r) ]

x only contains the root node, why?

Here's the full code; note that the BST implementation is correct, it's the inorder() implementation with generators that is somehow wrong.

class STree(object):
    def __init__(self, value):
        self.key = value
        self.left = None
        self.right = None

def insert(r, node):
    if node.key < r.key:
        if r.left is None:
            r.left = node
        else:
            insert(r.left, node)
    else:
        if r.right is None:
            r.right = node
        else:
            insert(r.right, node)

def inorder(t):
    if t:
        inorder(t.left)
        yield t.key
        inorder(t.right)


r = STree(10)
insert(r, STree(12))
insert(r, STree(5))
insert(r, STree(99))
insert(r, STree(1))

tree = [ n for n in inorder(r) ]
print tree
like image 340
laurids Avatar asked Apr 22 '15 13:04

laurids


1 Answers

inorder(t.left) only creates the generator object, it doesn't actually run it. You need to actually yield all the values produced by each of the sub-generators, like so:

def inorder(t):
    if t:
        yield from inorder(t.left)
        yield t.key
        yield from inorder(t.right)

Note that the yield from convenience syntax was only introduced in Python 3.3 so if you're using an older version you'll have to iterate over the sub-generators explicitly:

# Python 2
def inorder(t):
    if t:
        for key in inorder(t.left):
            yield key
        yield t.key
        for key in inorder(t.right):
            yield key
like image 96
tzaman Avatar answered Sep 28 '22 05:09

tzaman