「刷题」二叉树的题刷不动?快进来拓展解题思路!

本文介绍了如何在Java中实现对称二叉树的判断、层序遍历的数据结构算法,以及利用前序和中序遍历构建二叉树的过程。作者详细展示了递归方法的应用和关键步骤。
摘要由CSDN通过智能技术生成

🎇个人主页Ice_Sugar_7
🎇所属专栏数据结构刷题
🎇欢迎点赞收藏加关注哦!

🍉对称二叉树

题目链接

思路:现在有两个节点root1、root2,它们有共同的根节点,如果root1的左子树、右子树分别和root2的右子树、左子树相同,那就是对称的
需要注意的是,题干给的方法只有一个参数root,但是我们要两边同时走,也就需要两个参数,所以需要额外写一个方法

    public boolean isSymmetric(TreeNode root) {
        if(root == null) {
            return true;
        }
        return Symmetric(root.left,root.right);
    }

    public boolean Symmetric(TreeNode root1,TreeNode root2) {
        //整体思路是前序遍历,先对根节点进行判断
        if(root1 == null && root2 == null) {
            return true;
        }
        //到这里,root1和root2至少有一个不为空,接下来判断有没有一个是空的,若有,那就不是对称的了
        if(root1 == null || root2 == null) {
            return false;
        }
        //到这里,root1和root2都不为空
        //比较根节点的值
        if(root1.val != root2.val) {
            return false;
        } else {
            //从else开始就是遍历根节点的左子树和右子树
            boolean ret1 = Symmetric(root1.left,root2.right);
            boolean ret2 = Symmetric(root1.right,root2.left);
            if(ret1 && ret2) {
                return true;
            } else {
                return false;
            }
        }
    }


🍉层序遍历二叉树

题目链接

思路:用队列存储二叉树每一层的元素,定义一个变量size记录入队后队列的元素个数,也就是二叉树每一层的元素个数
为什么要记录呢?因为我们需要弹出这一层的节点,然后“带”出下一层的节点的,要知道弹出多少个节点

class Solution {
    Queue<TreeNode> queue = new LinkedList<>();

    public List<List<Integer>> levelOrder(TreeNode root) {
        if(root == null)
            return new ArrayList<>();
        List<List<Integer>> ret = new ArrayList<>();
        queue.offer(root);

        while(!queue.isEmpty()) {
            List<Integer> list = new ArrayList<>();
            int size = queue.size();

            //这个循环实现:将第k层的元素出队列,让第k+1层元素入队
            while(size-- > 0) {
                TreeNode top = queue.poll();  //取当前队头的元素
                list.add(top.val);  //每取出一个,就放到list里面
                if(top.left != null)
                    queue.offer(top.left);
                if(top.right != null)
                    queue.offer(top.right);
            }
            ret.add(list); //将list放进ret,相当于将一维数组放进二维数组
        }
        return ret;
    }
}

🍉由前序、中序遍历构造二叉树

题目链接

思路:根据前序遍历推出根节点,然后找出根节点在中序遍历数组中的位置,这样就能知道剩下的节点是在左子树还是右子树
在这里插入图片描述
在这里插入图片描述
以上图为例,由中序遍历的数组可知,20在以3为根节点的右子树,而在preorder中,20是右子树部分第一个数,说明它是这个右子树的根节点
(这里解释一下原因:因为前序遍历是按照根、左、右的顺序遍历的,所以遇到的第一个节点就是根节点)

以3为根节点分割好之后,继续对左右子树进行分割:先找出子树根节点在中序数组的位置,然后分割为更小的区间

class Solution {
    public int prei; //记录遍历到前序数组的哪个下标

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return devide(preorder,inorder,0,inorder.length - 1);
    }

    //val:要找的根节点的值
    public int findIndex(int val,int[] inorder) {
        for(int i = 0;i < inorder.length;i++) {
            if(inorder[i] == val) {
                return i;  //返回它在inorder中的下标
            }
        }
        return -1;
    }
    
	//begin、end:子树的起始、终止下标
    public TreeNode devide(int[] preorder,int[] inorder,int begin,int end) {
        //当end < begin时递归结束,注意end == begin时也要进行递归,此时也要创建节点
        if(end < begin)
            return null;

        //从中序遍历数组中找到“分割点”
        int dev = findIndex(preorder[prei++],inorder);  //dev:分割点在inorder中的下标
        //分割点就是根节点
        TreeNode node = new TreeNode(inorder[dev]);
        //通过递归连接左右子树
        node.left = devide(preorder,inorder,begin,dev-1);
        node.right = devide(preorder,inorder,dev+1,end);
        return node;
    }
}
  • 25
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值