开发者

left-right BFS travesal on a binary tree

开发者 https://www.devze.com 2023-01-19 07:05 出处:网络
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.

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 开发者_Python百科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).


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.


I just tried the above suggestion given by Potatoswatter in C#.I have not tried running it. Please correct me, if something needs to be modified.

void BFSTraversePrintzigzag(Node root)  

{  
    bool bLeftToRight = true;  
    Stack<Node> stack1=new Stack<Node>();  
    Stack<Node> stack2=new Stack<Node>();  
    stack1.Push(root);  
    //loop until both the stacks are empty  
    while(stack1.Count>0 ||stack2.Count>0)  
    {  
        //Stack1 will be empty when all the nodes on a level are traversed.   
        if (stack1.Count==0 && stack2.Count>0)  
        {  
            //Swap stack1 and stack2, if stack1 is empty  
            stack1= stack2;  
            while(stack2.Count>0)  
                stack2.Pop();  
            bLeftToRight=!bLeftToRight;  
            //This is the state variable to switch the order from left to right and from Right to left  
        }  
        root=stack1.Pop();  
        Console.WriteLine(root.data) ;  
        if(bLeftToRight)      
        {        
            if(root.left!=null)  
                stack2.Push(root.left);  
            if(root.right!=null)  
                stack2.Push(root.right);  
        }  
        else  
        {  
            if(root.right!=null)  
                stack2.Push(root.right);  
            if(root.left!=null)  
                stack2.Push(root.left);  
        }  
    }  
}  


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消