Monday, April 25, 2016

Yesterday we were discussing rebuilding a tree from post order and in order traversals.
We made the following observations:
1) the roots are found top down by walking the post order list in the reverse manner
2) the length of the right subtree for any root is given by the number of nodes between its position in the inorder and that of its parent.
3) the position of the left sibling in post order is at an offset equal to the length of the right subtree to the left of the root in post order. The position of the right sibling is immediately before the root.
4)  the length of the left subtree is the distance between the the position of the right sibling and the root in the in order.
6) The subtrees may be null and we just need to be mindful of the size but not need to check it upfront.

                    A

             B            C

        D      E          F     G

H    I    J    K         L   M    N    O
Post: H I D J K E B L  M F N O G C A
In:    H D I B J E K A  L  F M C N G O

Node Rebuild(List<Node> post, List<node> in) // All nodes in list initialized with left and right = null and set only with data
{
assert( post != null && in != null);
assert (posts.Count() == in.Count());

for(int i =  post.Count()-1; I >= 0; I--)
{
     Node root = post[i];
     int inIndex= Array.indexOf(in, post[i]);
     if ( I > 0 && I < post.Count())
     {
     Int parent = findParentIndex (Post, i); //parent occurs to the right of root in post with left,right set
     Int parentin = in.Count();// defaults to in.Count()
     if (parent < post.Count())
          parentin = Array.indexOf(in, post[parent]);
     Int righttreelen = parentIn-inIndex-1;
     if (i-righttreelen-1 > 0)
          Root.left = post [i-righttreelen-1];
     Int right = i-1;
     if (right > 0)
         Root.right = post [right];
}
return post[post.Count() - 1];
}

int findParentIndex(List<node>post, int current)
{
int target = post.Count();
for (int i = current+1; i< post.Count(); i++)
{
if ( post[i].left == post[current] ||
      post[i].right == post[current]){
     target  =  i;
     break;
     }
}
return target;
}

For performance gain, we also made the observation that the length of the right subtree need to be calculated only when we know that the right subtree is not null. We already know this if the index of the previous element (right sibling)  in post happens to have an inorder index less than that of the root.

No comments:

Post a Comment