二叉树的遍历——前中后序(递归,非递归)

二叉树的遍历

前序遍历:根节点–》根节点的左子树–》根节点的右子树
中序遍历:根节点的左子树–》根节点–》根节点的右子树
后序遍历:根节点的左子树–》根节点的右子树–》根节点
共同点:先坐子树后右子树
不同点:根节点的遍历次序不同
        二叉树的递归遍历非常简单,就拿前序遍历做个说明(来源–》力扣144. 二叉树的前序遍历):
创建一个数组,保存遍历结果,只要节点不为空,就保存结点,向左遍历完后向右遍历
二叉树中序和后序的递归遍历只需要改变递归的顺序

class Solution {
    List<Integer> arr=new ArrayList<>();
    public List<Integer> preorderTraversal(TreeNode root) {
        if(root!=null){
            arr.add(root.val);
            preorderTraversal(root.left);
            preorderTraversal(root.right);
        }
        return arr;
    }
}

以下是二叉树的非递归遍历👇👇👇

二叉树的前序遍历

       二叉树前序遍历的非递归遍历是借助栈(Stack)来实现的:先把根结点入栈,栈非空时元素出栈放到数组中,然后让右孩子和左孩子分别入栈(因为是先序遍历跟–》左–》右,所以先把右孩子入栈,再把左孩子入栈),代码(力扣144. 二叉树的前序遍历)和入栈出栈顺序如下:

/**
 * 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> preorderTraversal(TreeNode root) {
        List<Integer> ret=new ArrayList<>();
        if(root==null){
            return ret;
        }
        Stack<TreeNode> s=new Stack<>();
        s.push(root);
        while(!s.isEmpty()){
            TreeNode cur=s.pop();
            ret.add(cur.val);
            if(cur.right!=null){
                s.push(cur.right);
            }
            if(cur.left!=null){
                s.push(cur.left);
            }
        }
        return ret;
    }
}

在这里插入图片描述

二叉树的中序遍历

       二叉树的中序遍历,代码如下(力扣94. 二叉树的中序遍历):

/**
 * 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> inorderTraversal(TreeNode root) {
        List<Integer> ret=new ArrayList<>();
        if(root==null){
            return ret;
        }
        Stack<TreeNode> s=new Stack<>();
        TreeNode cur=root;
        while(cur!=null||!s.isEmpty()){
            while(cur!=null){
                 s.push(cur);
                 cur=cur.left;
            }
           TreeNode p=s.pop();
           ret.add(p.val);
           if(p.right!=null){
               cur=p.right;
           }
        }
        return ret;
    }
}

在这里插入图片描述

二叉树的后序遍历

       二叉树的后序遍历,代码如下(力扣145. 二叉树的后序遍历):

/**
 * 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> ret=new ArrayList<>();
        if(root==null){
            return ret;
        }
        TreeNode cur=root;
         TreeNode flag=null;
        Stack<TreeNode> s=new Stack<>();
        while(cur!=null||!s.isEmpty()){
            while(cur!=null){
                s.push(cur);
                cur=cur.left;
            }
            TreeNode p=s.peek();
            if(p.right==null||flag==p.right){
                flag=s.peek();
                ret.add(s.pop().val);
            }
            else{
                cur=p.right;
            }
        }
        return ret;       
    }
}

在这里插入图片描述
       后序遍历是在中序遍历的基础上添加一个标志位,确保结点的右孩子已经操作过,如果没有设置标志位,可能会导致结点不停的入栈出栈

总结

       二叉树的前中后序遍历都可以借助栈(Stack)来实现,前序遍历相对简单(但要注意在前序遍历中是右孩子先入栈,然后左孩子入栈),后序遍历比较难理解,需要在中序遍历的基础上还要考虑结点是否遍历过。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值