简体   繁体   中英

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.

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.

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;
        }
    }
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM