public ArrayList<Integer> postorderTraversal(TreeNode root) {
    ArrayList<Integer> result = new ArrayList<Integer>();
    if (root == null)
      return result;

    Stack<TreeNode> stack = new Stack<TreeNode>();
    stack.push(root);
    TreeNode prev = null;
    while (!stack.empty()) {
      TreeNode curNode = stack.peek();
      if (prev == null || prev.left == curNode || prev.right == curNode) {
        if (curNode.left != null)
          stack.push(curNode.left);
        else if (curNode.right != null)
          stack.push(curNode.right);
      } else if (curNode.left == prev) {
        if (curNode.right != null)
          stack.push(curNode.right);
      } else {
        result.add(curNode.val);
        stack.pop();
      }
      prev = curNode;
    }
    return result;
  }