力扣刷题二叉树前中后序遍历

Posted 王六六的IT日常

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣刷题二叉树前中后序遍历相关的知识,希望对你有一定的参考价值。

二叉树遍历系列

  • 前序遍历:打印 - 左 - 右
  • 中序遍历:左 - 打印 - 右
  • 后序遍历:左 - 右 - 打印

在树的深度优先遍历中(包括前序、中序、后序遍历),递归方法最为直观易懂,但考虑到效率,我们通常不推荐使用递归。

1. 力扣 - 二叉树的前序遍历
递归:
递归思路:先树根,然后左子树,然后右子树。每棵子树递归。

class Solution 
    public List<Integer> preorderTraversal(TreeNode root) 
        //前序遍历 根左右
        List<Integer> res = new ArrayList<>();
        preOrder(root,res);
        return res;
    

	//前序遍历
    public void preOrder(TreeNode root, List<Integer> res)
        if(root == null)
            return;
        
        //打印-左-右
        res.add(root.val);
        preOrder(root.left,res);
        preOrder(root.right,res);
    

迭代:
在迭代算法中,思路演变成,每到一个节点 A,就应该立即访问它。
因为,每棵子树都先访问其根节点。对节点的左右子树来说,也一定是先访问根。
在 A 的两棵子树中,遍历完左子树后,再遍历右子树。
因此,在访问完根节点后,遍历左子树前,要将右子树压入栈
思路:

S;
p= root;
while(p || S不空)
    while(p)
        访问p节点;
        p的右子树入S;
        p = p的左子树;
    
    p = S栈顶弹出;

class Solution 
    public List<Integer> preorderTraversal(TreeNode root) 
        //创建Integer类型的结果列表对象
        List<Integer> res = new ArrayList<>();

        if(root == null)
            return res;
        

        //创建类型为TreeNode的栈对象
        Stack<TreeNode> stack = new Stack<>();

        //根节点入栈
        stack.add(root);

        while(!stack.isEmpty())
            //栈顶元素出栈(栈为先进后出,所以右孩子先入栈)
            TreeNode cur = stack.pop();

            //将此节点的值加入结果中
            res.add(cur.val);

            //判断该节点的右孩子是否为空
            if(cur.right != null)
                //右孩子入栈
                stack.add(cur.right);
            

            //判断该节点的左孩子是否为空
            if(cur.left != null)
                //左孩子入栈
                stack.add(cur.left);
            
            
        
        return res;
    

2. 力扣 - 二叉树中序遍历
递归:
递归的调用过程是不断往左边走,当左边走不下去了,就打印节点,并转向右边,然后右边继续这个过程。

class Solution 
    public List<Integer> inorderTraversal(TreeNode root) 
        List<Integer> result = new ArrayList<>();
        //递归调用
        inOrder(root,result);
        return result;
    
	//中序遍历
    public void inOrder(TreeNode root,List<Integer> result)
        if(root == null)
            return;
        
		//左
        inOrder(root.left,result);
        //打印
        result.add(root.val);
        //右
        inOrder(root.right,result);

    

迭代:
模拟递归过程

class Solution 
    public List<Integer> inorderTraversal(TreeNode root) 
        //迭代
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();

        //模拟递归
        while(!stack.isEmpty()||root!= null)
				//不断往左子树方向走,每走一次就将当前节点保存到栈中
				//这是模拟递归的调用
            if(root != null)
                stack.add(root);
                root = root.left;
								//当前节点为空,说明左边走到头了,从栈中弹出节点并保存
								//然后转向右边节点,继续上面整个过程
            else
                //直到没有左孩子
                TreeNode cur = stack.pop();
                res.add(cur.val);
                root = cur.right;
            
        
        return res;

    

3. 力扣 - 二叉树的后序遍历
左-右-打印
递归:

class Solution 
    public List<Integer> postorderTraversal(TreeNode root) 
        List<Integer> res = new ArrayList<>();
        postOrder(root,res);
        return res;
    

    public void postOrder(TreeNode root,List<Integer> res)
        if(root == null)
            return;
        

        postOrder(root.left,res);
        
        postOrder(root.right,res);

        res.add(root.val);

    

迭代:
每到一个节点 A,就应该立即访问它。
然后将左子树压入栈,再次遍历右子树。遍历完整棵树后,结果序列逆序即可。

思路:

S;
p= root;
while(p || S不空)
    while(p)
        访问p节点;
        p的左子树入S;
        p = p的右子树;
    
    p = S栈顶弹出;

结果序列逆序;
class Solution 
    public List<Integer> postorderTraversal(TreeNode root) 
        //后序遍历:左右根
        //前序遍历:根左右---反转---->左右根
        List<Integer> res = new ArrayList<>();

        if(root == null)
            return res;
        

        Stack<TreeNode> stack = new Stack<>();
        //入栈
        stack.push(root);
        //栈不为空
        while(!stack.isEmpty())
            TreeNode cur = stack.pop();
            res.add(cur.val);

            //一直到左孩子为空跳出该循环
            if(cur.left != null)
                stack.push(cur.left);
            

            if(cur.right != null)
                stack.push(cur.right);
            

        

        //反转数组
        Collections.reverse(res);
        return res;

    

以上是关于力扣刷题二叉树前中后序遍历的主要内容,如果未能解决你的问题,请参考以下文章

二叉树前中后序遍历的实现(递归和非递归版)

已知二叉树前中序遍历,求后序 / 已知二叉树中后序遍历,求前序

二叉树前中后序遍历递归转循环

二叉树前中后序遍历_(非递归)

二叉树前中后序遍历_(非递归)

二叉树前中后序遍历递归法&迭代法