https://oj.leetcode.com/problems/binary-tree-postorder-traversal/

http://blog.csdn.net/linhuanmars/article/details/22009351


/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        
        // Solution A
        // List<Integer> toReturn = new ArrayList<>();
        // postorderTraversal_recursively(root, toReturn);
        // return toReturn;
        
        // Solution B
        return postorderTraversal_iteratively(root);
    }
    
    ///////////////////////
    //
    // Solution B: Iteratively
    //
    private List<Integer> postorderTraversal_iteratively_2(TreeNode root)
    {
        List<Integer> toReturn = new ArrayList<>();
        
        if (root == null)
            return toReturn;
            
        Stack<TreeNode> stack = new Stack<>();
        TreeNode pre = null;
        while (root != null || !stack.empty())
        {
            if (root != null)
            {
                stack.push(root);
                root = root.left;
            }
            else
            {
                TreeNode peekNode = stack.peek();
                if (peek.right == null || peek.right = pre)
                {
                    stack.pop();
                    toReturn.add(peekNode.val);
                    pre = peekNode;
                }
                else
                {
                    root = peek.right;
                }
            }
        }
    }

    ///////////////////////
    //
    // Solution B: Iteratively
    //
    private List<Integer> postorderTraversal_iteratively(TreeNode root)
    {
        List<Integer> toReturn = new ArrayList<>();
        if (root == null)
            return toReturn;
        
        // Define a stack.
        Stack<CheckedNode> stack = new Stack<>();
        stack.push(new CheckedNode(root, false));
        
        while (!stack.empty())
        {
            CheckedNode checkednode = stack.pop();
            
            if (checkednode.checked ||  // The node has been checked
               (checkednode.node.left == null && checkednode.node.right == null)) // A leaf node
            {
                // If the node has checked
                // Just add its value
                toReturn.add(checkednode.node.val);
            }
            else
            {
                // Checking this node.
                // Push it back, push its right, push its left
                checkednode.checked = true;
                stack.push(checkednode);
                if (checkednode.node.right != null)
                {
                    stack.push(new CheckedNode(checkednode.node.right, false));
                }
                if (checkednode.node.left != null)
                {
                    stack.push(new CheckedNode(checkednode.node.left, false));
                }
            }
        }
        return toReturn;
    }
    
    private static class CheckedNode
    {
        TreeNode node;
        boolean checked;
        CheckedNode(TreeNode node, boolean checked)
        {
            this.node = node;
            this.checked = checked;
        }
    }

    
    ///////////////////////
    //
    // Solution A: Recursively
    //
    
    private void postorderTraversal_recursively(TreeNode node, List<Integer> result)
    {
        if (node == null)
            return;
            
        postorderTraversal_recursively(node.left, result);
        postorderTraversal_recursively(node.right, result);
        result.add(node.val);
    }
}