views:

89

answers:

2

Hi all,

This is not a home work. I was thinking of some new questions in tree traversal and this seems to be very obvious so thought of solving it.

Question is very similar to level order traversal like BFS. In BFS, we normally travel left to right in each level of tree, but here if we are travelling left to right at level i then level (i-1) and (i+1) need to be traveled from right to left.

For Example:

           2
          / \
         7   5
        / \   \
       2   6   9
          / \   \
         5  11   4

In normal BFS, we output: 2, 7, 5, 2, 6, 9, 5, 11, 4

But i am looking a solution where we output: 2, 5, 7, 2, 6, 9, 4, 11, 5

I am able to come up a solution. But, i want to see if any one come up better solution then mine. I am particularly looking optimization in space complexity (stack size) as well.

Please give your logic in accordance with C++ language. I will greatly appreciate if you do not use any containers or STL in your solution.


Based on comments here, i have come up a solution using two stacks. My solution is as below.

  • Create stack S1 and S2 and queue Q. Queue Q will hold the final ans.
  • Note that before pushing in any stack (S1 or S2) we will first enqueue it into queue Q.
  • Whatever we pop from stack s1, we will push its (first) right child and (then) left child (in this order)into stack s2. (Be remember point 2)
  • Whatever we pop from stack s2, we will push its (first) left child and (then) right child (in this order) into stack s1. (Be remember point 2)
  • Pop from one stack and push it to another untill both the stacks are empty. final entries in Queue will be the ans.

/*
Create Stack S1, S2; // for tmp itr. Both of size log<n>
Create Queue Q; // It will hold ans
*/ 


Q.enqueue(root); //Enqueue the root nood;
S1.enqueue(root); //Fill the stack with somthing to start.



  while(S1||S2){                        // keep spinning untill both stack are empty.
        while(s1){                      //take care of stack S1.
            Node* tmp = S1.pop();       //take top elem;

        if(tmp->right){
            Q.enqueue(tmp->right);
            S2.push(tmp->right);
        }

        if(tmp->left){
            Q.enqueue(tmp->left);
            S2.push(tmp->left);
        }
    }

    while(S2){ //while S2 is not empty
        Node* tmp = S2.pop();

        if(tmp->left){
            Q.enqueue(tmp->left);
            S1.push(tmp->left);
        }

        if(tmp->right){
            Q.enqueue(tmp->right);
            S1.push(tmp->right);
        }

    }
} //End of outher while

while(Q){
    cout<< Q.pop()->data;   //output the entries in desired format.
}

It seems Ok to me (let me know if it is not). But still wondering if there can be any other solution possible (better than this).

+2  A: 

Rather than use a single queue, use a pair of stacks. When the current stack is empty, start popping nodes off the other one, and pushing their children onto a now-empty one.

So you have

  • Push 2 onto one of the stacks.
  • Pop 2 off of it, push 7 5 onto other one. Swap the stacks.
  • Pop 5, push 9.
  • Pop 7, push 6 2. Swap the stacks.

Etc.

You need a state variable to decide whether to push left or right first, as well.

Potatoswatter
will it work? How you are pushing in the stack for intermediate terms of tree.
Manish Shukla
@Manish: provided a workthrough. Is that good?
Potatoswatter
Ok. I think, we have to use two stacks here. I have understood your solution and writing an algo to accomplish this in optimal manner. I will post it here when it is done.
Manish Shukla
based on your comment i have come up solution which i have included below my question. Please check it and let me know if you have any suggestions to improve performance.
Manish Shukla
A: 

If I understand what you want, I'd use a priority queue instead of a stack. As keys for your priority queue, you need to store the level in the tree of the node and the order within that level. The comparison function will use the level as the primary key. For even levels, it'll use the order as the secondary key directly, but for odd levels it'll negate it. Depending on whether you consider the root of the tree level 0 or level 1, you may need to reverse which levels get used directly vs. negated.

Jerry Coffin