Piyali Thorat
Piyali Thorat

Reputation: 21

Iterative Post order traversal without visited array

I have recently started learning computer science and Java coding and came across Traversal techniques. I am writing a Java code using Stack. I have been with this issue and couldn't find any solution. Is there anyway we can implement Post Order traversal using only one stack (without any extra data structure or extra space) ?

I have tried doing it and here is my code.

class node {
int data;
node left, right;
node(int val){
    data = val;
    left = right = null;
}
}
 public class binaryt {

public static void postorder(node root) {
    node current = root;
    Stack<node> st = new Stack<>();
    System.out.println();
    System.out.print("Post-order : ");  
    while(current!=null) {
        st.push(current);
        current = current.left;
    }
    while(!st.empty()) {
        current = st.pop();
        if(current.right==null) {
            System.out.print(current.data+" ");
            current = null;
        }
        else {
            st.push(current);
            current = current.right;
            while(current!=null) {
                st.push(current);
                current = current.left;
            }
        }
    }
}
public static void main(String[] args) {
    node root=null;


    root = new node(12);
    root.left = new node(8);
    root.left.left = new node(2);
    root.left.right = new node(9);
    root.right= new node(16);
    root.right.left= new node(13);
    root.right.right= new node(18);

    postorder(root);
}

}

I am unable to find what's wrong with the code as it is going in infinite loop. If anyone could help me, that would be huge favor. Thank you so much.

Upvotes: 2

Views: 520

Answers (3)

Raj
Raj

Reputation: 727

This is what is happening in your code :

  1. first you are pushing 12,8 and 2 in the Stack

  2. Then there is no left child for 2 , so you come to while

  3. now 2 is popped out , and it has no right child, so now two values in stack 8,12

  4. Next comes 8 it has a right child, you are pushing 8 into Stack again.

  5. Now you are taking 9 as current and pushing it into Stack.

  6. Now you are checking left of 9 which is null.

  7. so you are again starting with while(!st.empty()) { loop which has elements 9, 8,12

  8. again same thing repeats and your while loop never ends

you can also see on console : Post-order : 2 9 9 9 9 ..... Continues

So that is the issue.

Below is a solution :

public static void postorderIter( node root) {
    if( root == null ) return;

    Stack<node> s = new Stack<node>( );
    node current = root;

    while( true ) {

        if( current != null ) {
            if( current.right != null ) 
                s.push( current.right );
            s.push( current );
            current = current.left;
            continue;
        }

        if( s.isEmpty( ) ) 
            return;
        current = s.pop( );

        if( current.right != null && ! s.isEmpty( ) && current.right == s.peek( ) ) {
            s.pop( );
            s.push( current );
            current = current.right;
        } else {
            System.out.print( current.data + " " );
            current = null;
        }
    }
}

Upvotes: 1

John Humphreys
John Humphreys

Reputation: 39294

The best way to learn these annoying algorithms is to suffer a bit and find your own solution that will stick in your brain - so you're doing the right thing. This one is always hard for me.

  • do

    • while(root != null)

      • push root.right to stack if not null
      • push root
      • root = root.left to stack
    • root = stack.pop()

    • if (root.right == stack.peek)
      • stack.pop()
      • push root to stack
      • root = root.right
    • else
      • print root
      • root = null;
  • while stack ! empty

Your Problem

So, there are probably a few general things wrong in the attempt you showed. But here's the one I'd fix first, then I think you'll be able to get the others:

  • You can't just go left down the whole tree to start with. You need to go left only after you check the right node and add it to the stack. Remember, a recursive implementation would already have the root/current frame existing, then it would call the left and right trees. So, that means the current frame goes last after the left and right calls finish. So, the function call stack logically holds the left sub-tree, then the right-sub-tree, then the current frame.

Upvotes: 1

vividpk21
vividpk21

Reputation: 384

Here's an example that relies on recursion to make it more readable.

public static void postorder(node root) {
    Stack<node> nodes = new Stack<>();
    node curr = root;

    postOrderRecursive(curr, nodes);

    int size = nodes.size();
    while(size > 0){

        System.out.println(nodes.elementAt(0).data);
        nodes.remove(0);
        size = nodes.size();
    }
}
private static void postOrderRecursive(node n, Stack<node> nodes){
    if(n.left != null)
        postOrderRecursive(n.left, nodes);
    if(n.right != null)
        postOrderRecursive(n.right, nodes);

    nodes.push(n);
}

Output given your initialization: 2 9 8 13 18 16 12

Upvotes: 0

Related Questions