【数据结构(八)上】二叉树经典习题

news2024/11/26 18:42:17

❣博主主页: 33的博客❣
▶文章专栏分类: Java从入门到精通◀
🚚我的代码仓库: 33的代码仓库🚚
🫵🫵🫵关注我带你学更多数据结构的知识

在这里插入图片描述

目录

  • 1.前言
  • 2.经典习题
    • 2.1相同的树
    • 2.2另一棵子树
    • 2.3翻转二叉树
    • 2.4平衡二叉树
    • 2.5对称二叉树
    • 2.6二叉树的构建及遍历
    • 2.7二叉树的分层遍历
  • 3.总结

1.前言

在上一篇文章中,博主主要介绍了树与二叉树的基本概念、二叉树概念及特性、遍历方式自己实现一棵二叉树,在这篇文章中,博主将继续与大家分享二叉树经典习题。

2.经典习题

2.1相同的树

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同:OJ链接
解题思路

递归思想:
1.如果p为空,q为空,那么就是两颗空树肯定相等
2.如果一个树为空另一棵树不为空那么一定不相等
3.如果都不为空,值相同才相等。
4.在递归判断左子树是否相等,右子树是否相等,只有左右子树都相等才是相同的树

class Solution {
    class TreeNode {
     int val;
      TreeNode left;
      TreeNode right;
      TreeNode() {}
      TreeNode(int val) { this.val = val; }
      TreeNode(int val, TreeNode left, TreeNode right) {
          this.val = val;
          this.left = left;
          this.right = right;
      }
  }
    public boolean isSameTree(TreeNode p, TreeNode q) {
         if(p==null&&q==null){
             return true;
         }
         //p、q有一个为空
         if(p==null&&q!=null||p!=null&&q==null){
             return false;
         }
         //两个都不为空,不相等
         if(p.val!=q.val){
             return false;
         }
         //两个都不为空且p=q
         return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
    }
}

2.2另一棵子树

给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树:OJ链接
解题思路

递归思想
1.如果其中一个为null那么就不是子树
2.如果是两棵相同的树,那么就为一定为子树
3.再递归看sub是否为左子树的子树,右子树的子树,如果都不是,则返回false

public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        if(root == null &&subRoot!=null|| subRoot == null&&root!=null) {
            return false;
        }
         if(isSameTree(root,subRoot)){
            return true;
        }        if(isSubtree(root.left,subRoot)){
            return true;
        }  if(isSubtree(root.right,subRoot)){
            return true;
        }
        return false;
    }  

2.3翻转二叉树

给你一棵二叉树的根节点 root ,翻转这棵二叉树:OJ链接
解题思路

1.判断是否为空树,判断这棵树是否只有根节点
2.再交换左右子树

public TreeNode invertTree(TreeNode root) {
         if(root==null||root.left==null&&root.right==null){
            return root;
        }
        TreeNode tmp= root.left;
        root.left=root.right;
        root.right=tmp;
        invertTree(root.left);
        invertTree(root.right);
        return root;
    }

2.4平衡二叉树

给定一个二叉树,判断它是否是 平衡二叉树(左右子树相差不超过1):OJ链接
解题思路

递归思想
1.先求一个树深度
2.求左子树的深度,再求右子树的深度,相差>1则不平衡
3.并且左子树和右子树的每一个个小树都要平衡

public boolean isBalanced(TreeNode root) {
        if(root==null){
            return true;
        }
        int left=MaxLength(root.left);
        int right=MaxLength(root.right);
        if (Math.abs(left-right)<=1&&isBalanced(root.right)&&isBalanced(root.left)){
            return true;
        }else {
            return false;
        }
    }
    public int MaxLength(TreeNode root){
        if (root==null){
            return 0;
        }
        int Left=MaxLength(root.left);
        int Right=MaxLength(root.right);
        return Left>Right?Left+1:Right+1;
    }

我们观察以上代码,我们发现在求长度的时候已经遍历了一次二叉树,但在求是否平衡的时候,每次递归又会再求高度再遍历数组,效率非常低。那有能不能在求高度的时候就可以判断子树是否平衡呢?答案是可以的,如下:

当求高度的时候先先判断左子树和右子树只差是否小于1,如果小于1就返回-1,就不会再往递归了。

public boolean isBalanced(TreeNode root) {
        if(root==null){
            return true;
        }
        return MaxLength(root)>0;
    }
    public int MaxLength(TreeNode root){
        if (root==null){
            return 0;
        }
        int Left=MaxLength(root.left);
        int Right=MaxLength(root.right);
       if(Left>=0&&Right>=0&&Math.abs(Left-Right)<=1){
           return Math.max(Left,Right)+1;
       }else return -1;
    }

2.5对称二叉树

给你一个二叉树的根节点 root , 检查它是否轴对称:OJ链接
解题思路

1.判断root是否为null
2.比较左子树和右子树是否对称
3.若其中一棵树为null,那么不对称,若都为null则对称
4.再判断,左子树的左节点是否等于右子树的右节点&&左子树的右节点等于右子树的左节点,依次递归。

class Solution {
        public boolean isSymmetric(TreeNode root){
        if(root==null){
            return true;
        }else {
            return isSymmetric(root.left,root.right);
        }
    }
    public boolean isSymmetric(TreeNode L,TreeNode R){
        if(L==null&&R==null){
            return true;
        }
        if(L==null&&R!=null||L!=null&&R==null){
                return false;
        }
        if(L.val!= R.val){
            return false;
        }
      return isSymmetric(L.left,R.right)&&isSymmetric(L.right,R.left);
    }
}

2.6二叉树的构建及遍历

读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树:OJ链接

解题思路

1.遍历字符串,不为#,就new一个Node,但在遍历字符串的时候,我们要把i设置为成员变量防止每次递归后i从0开始
2.遍历二叉树中序输出

class TreeNode{
    char val;
    TreeNode left;
    TreeNode right;

    public TreeNode(char val) {
        this.val = val;
    }
}
public class Main {
    static int i=0;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
            String str=in.nextLine();
            TreeNode root= createTree(str);
            inOrder(root);
        }
    }
    public static TreeNode createTree(String str) {
//        for (int i=0;i<str.length();i++) {
//            char ch = str.charAt(i);i每次则从0开始
        TreeNode root=null;
        if(str.charAt(i)!='#'){
            root=new TreeNode(str.charAt(i));
            i++;
            root.left=createTree(str);
            root.right=createTree(str);
        }else {
            i++;//不要担心i超出字符串长度的问题
        }
        return root;
    }
    public static void inOrder(TreeNode root){
        if(root==null){
            return ;
        }
        inOrder(root.left);
        System.out.print(root.val+" ");
        inOrder(root.right);
    }
}

2.7二叉树的分层遍历

分层遍历二叉树:OJ链接
解题思路

我们需要借助队列来实现,当root不为null时,那么我们将root入队,再将它出队打印,出对的时候我们添加左子树,添加右子树,循环上述操作,直到独队列为空。

public void order(TreeNode root){
        Queue<TreeNode> queue=new LinkedList<>();
        if(root==null){
            return;
        }
        queue.offer(root);
        while (!queue.isEmpty()){
            TreeNode cur=queue.poll();
            System.out.println(cur.val+" ");
            if(cur.left!=null){
                queue.add(cur.left);
            }
            if (cur.right!=null){
                queue.add(cur.right);
            }
        }

    }

除了递归的方式,还可以用非递归的方式:

public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> list=new ArrayList<>();
        if(root==null){
            return list;
        }
        Queue<TreeNode> queue=new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()){
            int size=queue.size();
            List<Integer> l=new ArrayList<>();
            while (size!=0){
                TreeNode cur=queue.poll();
                size--;
                l.add(cur.val);
                if(cur.left!=null){
                    queue.add(cur.left);
                }
                if (cur.right!=null){
                    queue.add(cur.right);
                }
            }
            list.add(l);
        }
        return list;
    }

3.总结

在这篇文章中,博主主要分享了比较容易的一些二叉树题目,我们发现在做二叉树的习题时,大多都有用到递归思想,因为二叉树的子树本身也是一棵二叉树,所以当同学们遇到关于二叉树的问题时,可以往递归方向思考。在下一篇文章中,将继续和大家分享二叉树中比较复杂的题目。

下期预告:二叉树经典习题(下)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1606800.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安宝特方案 | AR工业解决方案系列-工厂督查

在工业4.0时代&#xff0c;增强现实&#xff08;AR&#xff09;技术正全面重塑传统工业生产&#xff0c;在工厂监督领域&#xff0c;其应用不仅大幅提升了生产效率、监测准确性和规范执行程度&#xff0c;而且为整体生产力带来了质的飞跃。 01 传统挑战与痛点 在制造业生产流程…

机器视觉系统:磁瓦尺寸瑕疵缺陷检测的精准“裁判”(官网)

在电子、通讯和汽车行业中&#xff0c;磁瓦作为关键组件&#xff0c;其尺寸精度和表面质量至关重要。然而&#xff0c;在生产过程中&#xff0c;由于各种因素的影响&#xff0c;磁瓦可能会出现尺寸上的瑕疵和缺陷&#xff0c;如尺寸不符、厚度不均、边缘破损等。这些缺陷不仅影…

浅析STM32H750启动文件

目录 概述 1 启动文件介绍 1.1 启动文件功能 1.2 汇编语言指令 2 启动代码细节 2.1 分配栈空间 2.2 分配堆空间 2.3 中断向量表 2.4 复位程序 2.5 中断服务程序 2.5.1 CPU内部中断程序 2.5.2 CPU内部扩展中断程序 2.6 用户堆栈初始化 3 总结 概述 本文以startup_stm3…

GreatSQL 死锁案例分析

1.背景概述 客户业务发生死锁的报错&#xff0c;根据业务程序日志及业务流程&#xff0c;发现造成死锁的原因是&#xff1a;事务1 delete insert &#xff0c;事务2 delete insert 2个事务交替执行导致的死锁&#xff1b;由于GAP锁阻塞了插入意向锁&#xff0c;并且当delete…

基于1-wire总线的多路温度监测系统

前言 在现代工业生产和环境监测中&#xff0c;温度是一个关键的参数&#xff0c;它直接影响到生产过程的稳定性和产品质量。为了确保温度控制在安全和有效的范围内&#xff0c;需要一种可靠且高效的多路温度监测系统。随着微电子技术和传感器技术的发展&#xff0c;基于1-Wire…

Redis中的订阅发布(二)

订阅与发布 订阅频道 每当客户端执行SUBSCRIBE命令订阅某个或某些频道的时候&#xff0c;服务器都会将客户端与被订阅的频道 在pubsub_channels字典中进行关联。 根据频道是否已经有其他订阅者&#xff0c;关联操作分为两种情况执行: 1.如果频道已经有其他订阅者&#xff0c…

从零实现诗词GPT大模型:数据集介绍和预处理

专栏规划: https://qibin.blog.csdn.net/article/details/137728228 本章将介绍该系列文章中使用的数据集&#xff0c;并且编写预处理代码&#xff0c;处理成咱们需要的格式。 一、数据集介绍 咱们使用的数据集名称是chinese-poetry&#xff0c;是一个在github上开源的中文诗…

雨润万物生,酒伴谷雨行

谷雨&#xff0c;是中国传统二十四节气之一 标志着中国农历的春季即将结束&#xff0c;夏季即将来临。在古代中国, 谷雨时节是农民开始播种、收获的时节,也是酿酒的好季节。谷雨时节,气温适宜、湿度较高&#xff0c;是酵母繁殖和发酵的好时候。 谷雨时节酿酒不仅仅是普通人们…

37-2 Python 的 requests 库发送 POST 请求

准备 sqlilabs 靶场: 构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 一、发送 POST 请求 首先使用bp对 sqlilabs 靶场的第12关抓个包,了解这个关卡是如何发包的 打开靶场:本地ip+ /sqli-labs-master/Less-12/ 先随便输入个账号登录如…

Postman之页面简介 V9.31.0

Postman之页面简介 V9.31.0 一、顶部栏二、左部栏三、中部栏四、下部栏 一、顶部栏 &#xff08;1&#xff09;new选项框&#xff0c;生成新建请求、集合、环境等 &#xff08;2&#xff09;import选项框&#xff0c;可以导入文件、文件夹、链接、文本信息等 &#xff08;3&…

(2022级)成都工业学院数据库原理及应用实验四: SQL简单查询

写在前面 1、基于2022级软件工程/计算机科学与技术实验指导书 2、成品仅提供参考 3、如果成品不满足你的要求&#xff0c;请寻求其他的途径 运行环境 window11家庭版 Navicat Premium 16 Mysql 8.0.36 实验要求 在实验三的基础上完成下列查询&#xff1a; 1、查询所有…

穿越物联网的迷雾:深入理解MQTT协议

目录标题 1、MQTT简介核心特性 2、MQTT的工作原理通信过程 3、MQTT的消息质量&#xff08;QoS&#xff09;4、安全机制5、实践应用环境准备示例项目发布者客户端订阅者客户端 6、最佳实践7、结论8、参考资料 在物联网&#xff08;IoT&#xff09;的海洋中&#xff0c;数据像水流…

【ACM列表推荐会议 | EI稳定检索】2024年第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)

2024年第四届人工智能、自动化与高性能计算国际会议&#xff08;AIAHPC 2024&#xff09; 2024 4th International Conference on Artificial Intelligence, Automation and High Performance Computing 2024第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)将于20…

二叉树的最大深度 - LeetCode 热题 37

大家好&#xff01;我是曾续缘&#x1f61b; 今天是《LeetCode 热题 100》系列 发车第 37 天 二叉树第 2 题 ❤️点赞 &#x1f44d; 收藏 ⭐再看&#xff0c;养成习惯 二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最…

麒麟服务器操作系统自动化安装应答文件制作

原文链接&#xff1a;麒麟服务器操作系统自动化安装应答文件制作 Hello&#xff0c;大家好啊&#xff01;今天我们将探讨如何为麒麟服务器操作系统制作自动化安装应答文件。在部署大量服务器时&#xff0c;自动化安装是提高效率和确保安装一致性的关键技术。通过使用应答文件&a…

【计算机网络】ip子网划分--超详细例题解析

Hello!这一篇主要是计算机网络中的ip地址子网划分的例题&#xff0c;这里例举了四个题型。保证即便从0也可以掌握&#xff01;(前面是一些预备知识&#xff0c;不熟悉的小伙伴一定要看下学习下哦&#xff5e;) 这也是博主的学习过程&#xff0c;做题中仅仅我的理解哦。若文章中…

【k8s】:kubectl 命令设置简写启用自动补全功能

【k8s】&#xff1a;kubectl 命令设置简写&启用自动补全功能 1、设置kubectl命令简写2、启用kubectl自动补全功能 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; Kubernetes&#xff08;K8s&#xff09;是一个强大的容器编排平台&#…

Grid Controller

完整、易于使用的基于网格的第一人称控制器,具有《格里姆洛克传奇》、《地下城大师》和《巫师》的风格。 网格控制器是一种基于网格的第一人称控制器,设置简单,但具有鲁棒性和通用性。不需要脚本。 特征: 实时或基于回合的移动 平滑移动或即时捕捉到网格位置 倾斜、下降和蹲…

DevOps(七)Jenkins发布第一个流水线任务

Jenkins的流水线&#xff08;Pipeline&#xff09;是一种强大的工具&#xff0c;用于定义和管理持续集成和持续交付&#xff08;CI/CD&#xff09;过程。它允许你以代码的形式&#xff08;即"Pipeline as Code"&#xff09;定义整个构建、测试和部署流程&#xff0c;…

Linux中用户通过系统调用实现硬件驱动全流程

驱动全流程&#xff1a; 以基于设备树、Pinctrl、gpio子系统&#xff0c;打开一个字符设备为例&#xff1a; 1、通过系统调用open进入内核 当我们在用户空间调用open之后&#xff0c;应用程序会使用系统调用指令&#xff08;在上图中可看到&#xff0c;ARM架构中软中断汇编指…