You can construct the tree using the post-order traversal in O(n) using the following rationale:
- The last element is always the tree root
- All the previous elements greater than the root are part of the right subtree. All the elements lesser are part of the left subtree.
- You can apply the above rules recursively.
The construction from in-order is even more trivial. You just have to pick the middle element as root and call it recursively on both sides.
Here's an example implementation (in Python) that shows both constructions:
from collections import deque
def print_graphviz(tree):
if not isinstance(tree, tuple):
return tree
left = print_graphviz(tree[0])
right = print_graphviz(tree[2])
if left is not None: print tree[1], '->', left
if right is not None: print tree[1], '->', right
return tree[1]
def visit_post_order(in_queue, limit = None):
if len(in_queue) == 0 or in_queue[-1] < limit:
return None
root = in_queue.pop()
right = visit_post_order(in_queue, max(root, limit))
left = visit_post_order(in_queue, limit)
if left is None and right is None:
return root
else:
return (left, root, right)
def visit_in_order(in_order, begin, end):
if begin==end: return None
if begin+1==end: return in_order[begin]
mid = (begin+end)/2
root = in_order[mid]
left = visit_in_order(in_order, begin, mid)
right = visit_in_order(in_order, mid+1, end)
if left is None and right is None:
return root
else:
return (left, root, right)
def from_post_order(post_order):
return visit_post_order(deque(post_order))
def from_in_order(in_order):
return visit_in_order(in_order, 0, len(in_order))
print 'digraph {'
print print_graphviz(from_post_order([0, 2, 1, 4, 3, 6, 8, 7, 5]))
#print print_graphviz(from_in_order([1, 2, 3, 4, 5, 6, 7, 8]))
print '}'
Run like this:
python test.py | dot -Tpng | display
And you'll have a nice tree output:
