> Can anybody help me on how to construct Binary tree
> from inorder and postorder traversals,i just want to
> know the algorithm so that i can apply it.
Let p_1, p_2 ... p_n be the postorder traversal and let i_1, i_2 ... i_n
be the inorder traversal. From the postorder traversal we know that
the root of the tree is p_n. Find this element in the inorder traversal,
say i_1, i_2 ... i_k-1 p_n i_k+1 ... i_n. From the inorder traversal we
find all the elements in the left subtree, i.e. i_1, i_2 ... i_k-1 and in
the right subtree, i.e. i_k+1 ... i_n respectively.
Remove element p_n (and element i_k == p_n). Find the rightmost
element p_j in p_1, p_2 ... p_j ... p_n-1 where p_j is an element in
i_1, i_2 ... i_k-1. This is the root of the left subtree of the original tree.
Split p_1, p_2 ... p_j and p_j+1 ... p_n-1 and i_1, i_2 ... i_k-1 and
i_k+1 ... i_n. Now you have two subsequences representing the
postorder and inorder traversal of the two subtrees of the original
tree.
Apply the same steps recursively until all sequences are empty.
kind regards,
Jos
sequences representing the postorder traversal
Thanks very much Jos for giving the algorithm.Although i did knew how to do the things manually but was unable to write.!!THANKS
There is one more algorithm i am looking for and my book Cormen and all other books i have,and even goggling for the past half an hour comes to no rescue.
Algorithm is to Find the Diameter of the tree..i.e level number with maximum no. of nodes.
> Sure, but it doesn't mention anywhere how a tree can
> be constructed
> from two of the three pre/in/post-order traversals
> ...
>
> kind regards,
>
> Jos
Woops, thought the OP was a lazy student! (I didn't read the post with a lot of attention).
@OP: Sorry!
> Algorithm is to Find the Diameter of the tree..i.e
> level number with maximum no. of nodes.
Create an ArrayList a that keeps track of the number of nodes per level,
i.e. if a[ i ] == n, level i contains n nodes. Traverse the tree (pre/in/post,
it doesn't matter). and update that ArrayList a recursively. When you're
done, find the maximum value in ArrayList a.
kind regards,
Jos
>> How to find the number of nodes per level?
The idea is that you traverse the tree to find out. Start at the root; level = 0. Increase the node count of the current level by 1. Then for all of the children, increment the level and apply the same action. That way, when you're through, you'll have a list filled with node counts, of which you can select the max value.
> Jos it's very kind of you,but i have one doubt..
> How to find the number of nodes per level?
As I wrote (see above): update an ArrayList a where a[ i ] == n implies
that level i contains n nodes. Something like this:public void findDiameter(Node node, int level) {
if (node == null) return;
incrementLevelAt(level);
findDiameter(node.getLeft());
findDiameter(node.getRight());
}
kind regards,
Jos
> Let p_1, p_2 ... p_n be the postorder traversal and
> let i_1, i_2 ... i_n
> be the inorder traversal. From the postorder
> traversal we know that
> the root of the tree is p_n. Find this element in the
> inorder traversal,
> say i_1, i_2 ... i_k-1 p_n i_k+1 ... i_n. From the
> inorder traversal we
> find all the elements in the left subtree, i.e. i_1,
> i_2 ... i_k-1 and in
> the right subtree, i.e. i_k+1 ... i_n respectively.
>
> Remove element p_n (and element i_k == p_n). Find the
> rightmost
> element p_j in p_1, p_2 ... p_j ... p_n-1 where p_j
> is an element in
> i_1, i_2 ... i_k-1. This is the root of the left
> subtree of the original tree.
>
> Split p_1, p_2 ... p_j and p_j+1 ... p_n-1 and i_1,
> i_2 ... i_k-1 and
> i_k+1 ... i_n. Now you have two subsequences
> representing the
> postorder and inorder traversal of the two subtrees
> of the original
> tree.
chanced upon this forum.
i would just like to ask if i can do that algorithm on the two arrays or i need to "split" it into two ("left son" and "right son") arrays.
I would like to pick a minor little nit with this analysis. The algorithm that has been proposed assumes that all the nodes are all distinct and that having selected the root from the end of the post-order listing that it is POSSIBLE to find it in the in-order list. What if you find multiple copies of this node?
If multiple copies of the root are found, you must have a method to distinguish, which one is the proper dividing point. In the worst possible case, the problem can not be solved at all. For example suppose my post-order and my in-order lists were these:
a a a a a
a a a a a
The shape of the tree is indeterminant in this case.
If you allow different tree nodes to contain identical values your recursive algorithm needs some modification.
The fix is this:
1) allow your recursive algorithm to fail (and report back any success or failure)
This can and happen if the two lists that you passed in are incompatible. For example they could have different nodes in them.
2) when you pick the root off the end of the post order list, you search for it in the in-order list, you could find multiple matches or you could find no matches. You must explore each of these independently because each one could lead to a possible different solution, or could lead to no solution. Of course in the case of no matches, you must report back a failure.
Depending on your needs, you can either stop the first time that you have successfully assembled a tree that matches the two supplied inputs, or you can have it grind on and have it enumerate all the possible tree arrangements that could have generated from the two traversals that you started with.
It might help to visualize if you write out all the possible trees with just the three nodes AAB. There are 15 of them, 5 with B at the root, 5 with A at the root and B in the left and 5 with B in the right. It is easy to draw the trees and to immediately write both their in-order and their post-order traversals.
Any traversal is just a list of the 3 nodes and there are 3 arrangements, AAB, ABA, and BAA. There are exactly 9 ordered pairs of these traversals so you can't get all 15 trees from the 9 pairs.
Sho nuff, three ordered pairs are unambiguous and generate a single unique tree(e.g. in:BAA post:ABA) and six of them come from ambiguous pairs of trees (e.g. in:ABA post:ABA - you can't tell if this is a tree ABA all leaning to the left or all leaning to the right)
Enjoy
Assuming there are no repeated labels, how can one construct the binary tree? I'm stumped with the first given algorithm.
Given:
Postorder: LEYPCZHSGTA
Inorder: LEZYCPATHGS
what am i supposed to do after
LEYPCZHSGT
LEZYCP*THGS
that's the part after i've removed the root and has separated the two sequences...
my friend used the postorder sequence for getting the labels then used inorder for knowing its place in the binary tree...
Given:
Postorder: LEYPCZHSGTA
Inorder: LEZYCPATHGS
when i'm in 'H' from the postorder sequence, how would i know its parent? she said she used a stack. i'm still however clueless how it can work on other sequences.. help...
> help...
The following output I got from an implementation of Jos' recursive algoritm.
Ok, here we go:
===================================================
postorder = [L, E, Y, P, C, Z, H, S, G, T, (A)]
inorder= [L, E, Z, Y, C, P, (A), T, H, G, S]
root = 'A', level = 0
We find that 'A' is the root. Mark this one also
in the inorder traversal. Now look for the first
occerrence in the postorder traversal (from right
to left!) which is also in [L, E, Z, Y, C, P].
This is 'Z', and will get the following:
===================================================
postorder = [L, E, Y, P, C, (Z)]
inorder= [L, E, (Z), Y, C, P]
left root = 'Z', level = 1
So 'Z' is the left root. Look again for the first
occurrence of a character in the postorder (right
to left) which is in [L, E]. So we get:
===================================================
postorder = [L, (E)]
inorder= [L, (E)]
left root = 'E', level = 2
===================================================
postorder = [(L)]
inorder= [(L)]
left root = 'L', level = 3
===================================================
postorder = [Y, P, (C)]
inorder= [Y, (C), P]
right root = 'C', level = 2
===================================================
postorder = [(Y)]
inorder= [(Y)]
left root = 'Y', level = 3
===================================================
postorder = [(P)]
inorder= [(P)]
right root = 'P', level = 3
===================================================
postorder = [H, S, G, (T)]
inorder= [(T), H, G, S]
right root = 'T', level = 1
===================================================
postorder = [H, S, (G)]
inorder= [H, (G), S]
right root = 'G', level = 2
===================================================
postorder = [(H)]
inorder= [(H)]
left root = 'H', level = 3
===================================================
postorder = [(S)]
inorder= [(S)]
right root = 'S', level = 3
===================================================
finally done!
; )
This represents the following tree:
level
A0
/ \
/\
ZT 1
/ \\
ECG2
// \/ \
LYP HS3
Hope this helps a bit.
>===================================================
>postorder = [(L)]
>inorder = [(L)]
>left root = 'L', level = 3
>===================================================
one big trouble i'm having is i can't convert this algo into c or java. after exhausting the left subtree, i don't know what to do next for referencing the right subtree coming from the bottommost level of the left sub tree...
if this may sound easy, i really really really need your help...
> if this may sound easy, i really really really need
> your help...
This is the method I used:
private void constructTree(List<Character> postOrder, List<Character> inOrder, int level) {
level++;
Character root = /* the last element from the postOrder (use List.remove(...)) */;
List<Character> leftSubtree = /* this is: inOrder[0, ..., indexOf(root)] */;
Character leftRoot = null;
for(int i = postOrder.size()-1; i >= 0; i--) {
/*
the 'leftRoot' is defined as the first character
which is in 'leftSubtree' and in 'postOrder'
*/
}
System.out.println( /* print the root and the level */ );
List<Character> newPostOrderA, newInOrderA, newPostOrderB, newInOrderB;
newPostOrderA = /* is: postOrder[0, ..., postOrder.indexOf(leftRoot)+1] */;
newInOrderA= /* is: inOrder[0, ..., inOrder.indexOf(root)] */;
if(/* there are elements in 'newPostOrderA' */) {
System.out.print("left ");
/* make a recursive call with these new left in- and postorder traversals */
}
newPostOrderB = /* is: postOrder[postOrder.indexOf(leftRoot)+1, ..., postOrder.size()] */;
newInOrderB= /* is: inOrder[inOrder.indexOf(root)+1, ..., inOrder.size()] */;
if(/* there are elements in 'newPostOrderB' */) {
System.out.print("right ");
/* make a recursive call with these new right in- and postorder traversals */
}
}
I've commented some things out. It's for you to finish it.
Good luck.
Ater you split the in-order tree, you know know the size of the two sub trees so you can split the reaminder of the post-order into its two subtrees since they must match the sizes. This gives you an in and post pair for the left subtree of the root and also an in and post pair for the right subtree.
Given:
Postorder: LEYPCZHSGTA
Inorder: LEZYCPATHGS
1)find last elt of post order in the in order,
2)count the sizes of the two subtrees from the in order and split the post order by that same count
(LEYPCZHSGTA-LEZYCPATHGS)
1: (LEYPCZHSGT[A]-LEZYCP[A]THGS)
2: (A(LEYPCZ-LEZYCP)(HSGT-THGS))
recurse
1: (A(LEYPC[Z]-LE[Z]YCP)(HSG[T]-[T]HGS))
2: (A(Z(LE-LE)(YPC-YCP))(T()(HSG-HGS)))
recurse
1: (A(Z(L[E]-L[E])(YP[C]-Y[C]P))(T()(HS[G]-H[G]S)))
2: (A(Z(E(L-L)())(C(Y-Y)(P-P))(T()(G(H-H)(S-S))))
eventually you get
(A(Z(E(L()())())(C(Y()())(P()()))(T()(G(H()())(S()()))))
/*
A
ZT
ECG
LY PH S
*/
it's been a long time since i last visited here. hmmm...
i guess i'll try it in recursive next time. i have a new problem, which is finding the longest path given a graph.
btw, since i really had a hard time understanding the recursive approach... i used an iterative way. Also, our prof required us to use pointers. so, i was forced to used turbo c.
i'll study the algo that you gave... thanks!!! thank you so much!!!!
> i guess i'll try it in recursive next time. i have a
> new problem, which is finding the longest path given
> a graph.
Please start a new thread for this question. The subject Constructing Binary tree would be a bit off for this.
When you make a new thread, please show that you've given it a thought yourself. Write the code/pseudo-code of the things you've tried. Explain what it is that's giving you trouble.
> i'll study the algo that you gave... thanks!!! thank
> you so much!!!!
You're welcome.
> Please start a new thread for this question. The
> subject Constructing Binary tree would be a
> bit off for this.
> When you make a new thread, please show that you've
> given it a thought yourself. Write the
> code/pseudo-code of the things you've tried. Explain
> what it is that's giving you trouble.
I found an existing forum about my question. I was not exactly asking for any help regarding my new problem in this forum. but, thanks for the tip as regards making new threads!
thanks again!!