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

❣博主主页: 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.总结

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

免费开源圈子社交交友社区系统 可打包小程序 支持二开 源码交付!

线上社交的好处&#xff1a; 当今社会&#xff0c;人们越来越依赖于网络社交。互联网无疑为人类带来了许多好处&#xff0c; 其中一个就是线上社交。通过各种社交平台&#xff0c;人们可以随时随地互动交流&#xff0c;扩大自 己的社交圈&#xff0c;丰富生活。但是&#xf…

智慧水务能效管理系统平台/地下污水厂配电系统电气安全设计

安科瑞电气薛瑶瑶18701709087 1、引言 地下水污厂在城市建设中扮演着重要的角色,负责对城市污水和废物进行处理和排放。然而,由于地下水污厂中存在着许多危险因素,如有害气体、液体和固体废物等,因此要保证电气安全。电气安全系统是地下水污厂安全生产的重要保障措施之一,包括…

常见的软件架构模式

在软件开发过程中&#xff0c;软件架构模式是实现高质量、可扩展系统的关键。本文将介绍一些常见的软件架构模式&#xff0c;分析其优缺点和适用场景&#xff0c;从而帮助大家在实际项目中做出更明智的架构选择&#xff08;注意以下的架构模式相互之间并不一定互斥&#xff0c;…

imx6ull设备树驱动--pinctl、ioctl

添加pinctl节点 进入arch/arm/boot/dts目录下dts文件 在iomuxc下添加pinctlled节点 将 GPIO1_IO03 这个 PIN 复用为 GPIO1_IO03&#xff0c;电气属性&#xff08;配置GPIO一些列寄存器&#xff09;值为 0X10B0 添加led设备节点 与上一节一样&#xff0c;在 / 下面添加设备节…

2024年遥感技术与地理信息国际学术会议(ICRSTGI 2024)

2024年遥感技术与地理信息国际学术会议(ICRSTGI 2024) 2024 International Conference on remote sensing technology and geographic information 一、【会议简介】 2024年遥感技术与地理信息国际学术会议&#xff0c;将汇集世界各地的顶级专家和学者。 在这个会议上&#xf…

Springboot+Vue项目-基于Java+MySQL的网上购物商城系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

交通公路气象站:监测公路沿线气象

TH-GQX8交通公路气象站是一种专门用于监测公路沿线气象状况的设备系统。它通常由分布在公路沿线的若干个自动气象站联网组成&#xff0c;主要任务是实时监测和记录多种气象数据&#xff0c;为交通管理部门和驾驶员提供准确的路况信息。这些气象数据包括气温、湿度、风速、风向、…

高速公路交通运输大数据平台解决方案

前言 交通运输行业面临着多重挑战。其管控困难&#xff0c;涉及广泛地理范围&#xff0c;导致监控成本高且难以及时响应&#xff1b;同时&#xff0c;行业内数据量大&#xff0c;地理信息数据繁多&#xff0c;缺乏高效的可视化工具来揭示数据规律并优化业务&#xff1b;货运和…

润石科技(RUNIC)汽车电子应用方案和物料选型

一、润石科技&#xff08;RUNIC&#xff09;简介 江苏润石科技有限公司是一家专注于高性能、高品质模拟/混合信号集成电路研发和销售的高科技半导体设计公司。公司主要产品线分为两类&#xff1a;信号链和电源管理&#xff0c;其中信号链包含运算放大器、比较器、模拟开关、数…

微信小程序开发

微信小程序隶属于前端&#xff0c;因此我们只需要了解掌握一些基本的功能与业务逻辑即可。 HttpClient HttpClient 是Apache Jakarta Common 下的子项目&#xff0c;可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包&#xff0c;并且它支持 HTTP 协议…

APP自动化测试-Android SDK SDK Manager.exe或者uiautomatorviewer.bat打不开,点击就一闪而已的原因

原因是找不到Java.exe的路径&#xff0c; 如果是uiautomatorviewer.bat打不开&#xff0c;则使用文本编辑器打开它&#xff0c;然后添加java安装路径 set java_exeC:\Program Files\Java\jdk1.8.0_321\bin\java.exe 同理&#xff1a; 如果是SDK Manager.exe和AVD Manager.ex…

一个不同长度元素排序找行和列的需求

1、需求&#xff1a;三种长度的元素&#xff0c;分别是4、8、12&#xff0c;每一行的长度是12&#xff0c;超过12就排到下一行&#xff0c;我们将这三种类型的多个元素打乱&#xff0c;然后找到这些元素对应的行和列。 如下图&#xff1a; 2、解决思路&#xff1a; 创建一个长…

Java中的构造器

即使在类中什么都不写也会自动的生成一个构造器 注意 使用new关键字是在调用构造器 如果定义了有参构造 那么就不会默认的走Person person new Person();如果没有自己手动的定义无参构造就不能使用 在idea中 用按键Altinsert可以快速生成有参、无参构造&#xff08;某些品牌的…

SpringBoot:SpringMVC(下)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、RequestBody补充二、PathVariable三.RequestPart:四.ResponseBody五.CookieValue&#xff0c;SessionAttribute&#xff0c;RequestHeader 前言 提示&…

window下qt可执行程序打包

添加软件图标 方法1&#xff1a; QApplication a(argc, argv);// 设置应用程序图标QIcon appIcon("C:/Users/Administrator/Desktop/otp.png"); // 替换为你的图标文件路径a.setWindowIcon(appIcon); 缺点&#xff1a;运行后才显示图标&#xff0c;可执行程序文件图…

集成触发器(数电笔记)

同步触发器&#xff1a; 主从触发器&#xff1a; 边沿触发器&#xff1a;

2024年怎么购买阿里云5年云服务器?购买5年有什么优惠?(图文教程)

2024年阿里云优惠活动中的服务器大多数都是针对新用户&#xff0c;而且时长都变成了1个月或者1年&#xff0c;比较符合大多数用户的需求&#xff0c;不过有些用户由于需要长期使用云服务器&#xff0c;需要一次买5年&#xff0c;但是现在活动中的云服务器又没有5年的了&#xf…

边缘计算的优势

边缘计算的优势 边缘计算是一种在数据生成地点附近处理数据的技术&#xff0c;而非传统的将数据发送到远端数据中心或云进行处理。这种计算模式对于需要快速响应的场景特别有效&#xff0c;以下详述了边缘计算的核心优势。 1. 降低延迟 边缘计算通过在数据源近处处理数据&…

opencv基础篇 ——(三)图像二值化

opencv基础篇 ——&#xff08;三&#xff09;图像二值化 图像二值化是图像处理中常用的一种技术&#xff0c;用于将灰度图像转换为只包含两个像素值&#xff08;通常是黑色和白色&#xff09;的二值图像。这种处理通常用于简化图像、减少数据量以及强调感兴趣的目标。 二值化…

vue3中web前端JS动画案例(二)多物体运动-多值运动

<script setup> import { ref, onMounted, watch } from vue // ----------------------- 01 js 动画介绍--------------------- // 1、匀速运动 // 2、缓动运动&#xff08;常见&#xff09; // 3、透明度运动 // 4、多物体运动 // 5、多值动画// 6、自己的动画框架 // …