二叉树的后序遍历,即按照左右根的顺序遍历二叉树,常规的解题思路有三种,分别是递归、根右左遍历后倒置和迭代法。其中,递归方式最为简单,不再赘述;根右左遍历后倒置解法是前序遍历的变体,可参考144. 二叉树的前序遍历 - 掘金 (juejin.cn),但其本质是一种投机取巧,骗兄弟可以,别把自己也骗了。最后,迭代法是三种解法中最难的一种,也是三种遍历(前、中、后序遍历)方式中迭代解法最难的一种。
使用迭代解法时,对于每个根节点,会被访问三次:第一次,沿最左方向往下找最左节点;第二次,左子节点访问完之后返回根节点;第三次,右子节点访问完之后返回根节点。与前、中序遍历方式不同的是,后序遍历中的根节点,直到被第三次访问时,才能出栈并被记录进结果集。
那么如何知道根节点此时是第三次被访问呢?由以上推论可知,当上一个被访问的节点是根节点的右子节点时,此时根节点才是第三次被访问。
完整代码如下:
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode prev = null;
while (root != null || !stack.isEmpty()) {
if (root == null) {
TreeNode peek = stack.peek();
if (peek.right == null || peek.right == prev) {
TreeNode pop = stack.pop();
res.add(pop.val);
prev = pop;
root = null;
} else {
root = peek.right;
prev = root;
}
} else {
stack.push(root);
prev = root;
root = root.left;
}
}
return res;
}