5

Hello all—I'm a programming newcomer, and have the following very simple code here:

def postorder(T):
    if T != None:
        postorder(T.left)
        postorder(T.right)
        print T.data,

All I want is instead of printing the traversal I want to have the function store that information in an array or something of the like such that I can then use that information for other things

Simeon Visser
  • 118,920
  • 18
  • 185
  • 180
Aaron Ramsey
  • 63
  • 1
  • 1
  • 7
  • Aaron: please note that python has a (default) limit of 2000 frames. This means that any recursive solutions will StackOverflowError with large input. This is why I always do a second step of refactoring to a non-recursive stack/queue solution. – bukzor Nov 05 '13 at 18:14
  • @bukzor Even without a perfectly-balanced binary tree, you're more likely to run out of memory before running out of stack frames – Izkata Nov 05 '13 at 19:51
  • @Izkata: A linked list of length 3000 (aka the perfectly-unbalanced tree) will fit into memory quite easily. In my rough profile it took 22MB. – bukzor Nov 05 '13 at 20:01

2 Answers2

8

You can do:

def postorder(tree):
    data = []

    def recurse(node)
        if not node:
            return
        recurse(node.left)
        recurse(node.right)
        data.append(node.data)

    recurse(tree)
    return data

The inner function recurse takes care of traversing over the tree and the data is automatically added to data.

Simeon Visser
  • 118,920
  • 18
  • 185
  • 180
1

You could pass in a callable object, or you could write a generator:

def postorder(T):
    if T != None:
        postorder(T.left)
        postorder(T.right)
        print T.data,

def postorder_func(T, f):
    if T != None:
        postorder_func(T.left, f)
        postorder_func(T.right, f)
        f(T.data)

def postorder_gen(T):
    if T != None:
        for i in postorder_gen(T.left):
            yield i
        for i in postorder_gen(T.right):
            yield i
        yield T.data


class T:
    def __init__(self, left = None, data = None, right = None):
        self.left = left
        self.data = data
        self.right = right

one_half = T(data=.5)
three_halves = T(data=1.5)
one = T(one_half, 1, three_halves)
three = T(data=3)
root = T(one, 2, three)

postorder(root)
print ""

a = []
postorder_func(root, a.append)
print a

a = list(postorder_gen(root))
print a

Or, a one-liner solution:

def postorder_one(T):
    return [] if T is None else postorder_one(T.left)+[T.data]+postorder_one(T.right)
Robᵩ
  • 163,533
  • 20
  • 239
  • 308