给定一个二叉树,返回它的 后序 遍历。
输入: [1,null,2,3]
1
\
2
/
3
输出: [3,2,1]
非递归(迭代):
后序遍历递归定义:先左子树,后右子树,再根节点。
后序遍历的难点在于:需要判断上次访问的节点是位于左子树,还是右子树。
若是位于左子树,则需跳过根节点,先进入右子树,再回头访问根节点;
若是位于右子树,则直接访问根节点。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<Integer>();
if(root == null) return list;
TreeNode cur = root;
TreeNode pre = null;
Stack<TreeNode> stack = new Stack<>();
//把currentNode移到左子树的最下边
while(cur != null){
stack.push(cur);
cur = cur.left;
}
while(!stack.isEmpty()){
cur = stack.pop();
//一个根结点被访问的前提是:无右子树或右子树已被访问过
if(cur.right == null || pre == cur.right){
//访问
list.add(cur.val);
//修改最近被访问的节点
pre = cur;
}else{
//根结点再次入栈
stack.push(cur);
//进入右子树,且可以肯定右子树一定不为空
cur = cur.right;
while(cur != null){
//再次走到右子树的最左边
stack.push(cur);
cur = cur.left;
}
}
}
return list;
}
}
递归:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
List<Integer> list = new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
postorder(root);
return list;
}
public void postorder(TreeNode root){
if(root != null){
postorder(root.left);
postorder(root.right);
list.add(root.val);
}
}
}