【Java数据结构】二叉树详解(三)

news2024/10/5 19:59:39

🔒文章目录:

1.❤️❤️前言~🥳🎉🎉🎉

2. 检查两颗树是否相同

3. 另一颗树的子树

4.翻转二叉树

5.对称二叉树

6.判断一颗二叉树是否是平衡二叉树 

6.1第一种思路 

6.2第二种思路 

7.二叉树的构建及遍历 

8.总结 


1.❤️❤️前言~🥳🎉🎉🎉

Hello, Hello~ 亲爱的朋友们👋👋,这里是E绵绵呀✍️✍️。

如果你喜欢这篇文章,请别吝啬你的点赞❤️❤️和收藏📖📖。如果你对我的内容感兴趣,记得关注我👀👀以便不错过每一篇精彩。

当然,如果在阅读中发现任何问题或疑问,我非常欢迎你在评论区留言指正🗨️🗨️。让我们共同努力,一起进步!

加油,一起CHIN UP!💪💪

🔗个人主页:E绵绵的博客
📚所属专栏:

1. JAVA知识点专栏

        深入探索JAVA的核心概念与技术细节

2.JAVA题目练习

        实战演练,巩固JAVA编程技能

3.c语言知识点专栏

        揭示c语言的底层逻辑与高级特性

4.c语言题目练习

        挑战自我,提升c语言编程能力

📘 持续更新中,敬请期待❤️❤️

上篇文章我们讲完二叉树的基本知识点后,这篇文章将会给大家讲解一些二叉树的习题。 

2. 检查两颗树是否相同

 📌题目描述

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

📋题目思路 

首先,判断 p 和 q 是否为 null,如果有且只有一个为 null,则说明两棵树不相同,直接返回 false。如果两个树都不为 null,再判断它们的节点值是否相等,如果不相等则返回 false。如果相等则之后递归比较两个树的左右子树是否相同,如果都相同则返回 true,但凡有不同则直接返回false。 

⏳题目代码 

   //检查两颗二叉树是否相同。
    public boolean isSameTree(BTNode p, BTNode q) {
        if ((p != null && q == null) || (p == null && q != null))
            return false;
        if (p != null && q != null) {
            if (p.value != q.value)
                return false;
        }
        if (p == null && q == null)
            return true;

        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }

该题链接:检查两棵树是否相同


3. 另一颗树的子树

 📌题目描述

给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。

二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

 📋题目思路 

实现一个函数为isSubtree,用于判断二叉树 root 是否包含和 subRoot 具有相同结构和节点值的子树。

具体来说,首先调用一个我们在第一题中已经实现的函数 isSameTree(已经实现过该函数了,在这就不说了),判断 root 和 subRoot 是否完全相同(即结构和节点值都相同)。若相同则返回 true,否则继续递归调用isSubtree函数去判断 root 的左右子树中是否包含和 subRoot 相同的子树。只要有一个子树满足条件即可返回 true。若遍历完整个树仍未找到相同的子树,则返回 false。

 ⏳题目代码 

​//给你两棵二叉树 root 和 subRoot 。
//检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。
//如果存在,返回 true ;否则,返回 false 。

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

        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }

​

该题链接:另一颗树的子树 


 4.翻转二叉树

  📌题目描述

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。


 📋题目思路 

具体步骤为:

  1. 首先判断当前节点是否为空,如果为空则返回null。
  2. 判断当前节点的左右子树是否都为空,如果不都为空,则交换左右子树。
  3. 递归反转左子树。
  4. 递归反转右子树。
  5. 最后返回反转后的二叉树的根节点。

 ⏳题目代码 

//给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
public BTNode invertTree(BTNode root) {
if (root == null)
return null;
if (root.left != null || root.right != null) {
BTNode temp = root.right;
root.right = root.left;
root.left = temp;


    }
    if (root.left != null)
        invertTree(root.left);
    if (root.right != null)
        invertTree(root.right);
    return root;
}

该题链接:翻转二叉树


5.对称二叉树

 📌题目描述

给你一个二叉树的根节点 root , 检查它是否轴对称。


  📋题目思路 

具体实现方法为:

首先判断二叉树的根节点是否为null,若为null则返回true,因为空树是对称的。

接着调用check函数,该函数的参数是二叉树的左右子树。

在check函数中,首先判断左右子树是否都为null,若是则返回true;若有一个为null而另一个不是,则返回false,因为左右子树不对称。

若左右子树都不为null,则判断它们的值是否相等,若不相等则返回false。

最后,递归调用check函数判断左子树的左子树和右子树的右子树是否对称,以及左子树的右子树和右子树的左子树是否对称,若都对称则返回true,否则返回false。

⏳题目代码  

 //给你一个二叉树的根节点 root,检查它是否轴对称。(用了两个方法)
    public boolean isSymmetric(BTNode root) {
        if (root == null)
            return true;
        return check(root.left, root.right);
    }

    public boolean check(BTNode rootLeft, BTNode rootRight) {
        if (rootLeft == null && rootRight == null)
            return true;
        if ((rootLeft == null && rootRight != null) || (rootLeft != null && rootRight == null))
            return false;
        return (rootLeft.value == rootRight.value)
                && check(rootLeft.left, rootRight.right)
                && check(rootLeft.right, rootRight.left);
    }

该题链接:对称二叉树 


6.判断一颗二叉树是否是平衡二叉树 

 📌题目描述

给定一个二叉树,判断它是否是 平衡二叉树



6.1第一种思路 


 📋题目思路 

实现一个判断二叉树是否为平衡二叉树的方法。该方法接收一个 BTNode 类型的参数 root,表示二叉树的根节点,返回一个 boolean 类型的值,表示该二叉树是否为平衡二叉树。

首先判断当前节点是否为 null,若为 null 则返回 true,因为空树也可以看作是平衡二叉树。接着分别计算当前节点左右子树的高度,通过递归调用 getHeight 方法实现。最后判断当前节点的左右子树的高度差是否小于等于 1,若是则继续递归判断其左右子树是否为平衡二叉树,若均为平衡二叉树,则返回 true;否则返回 false。

注意:该代码在递归过程中,每个节点会被遍历多次,所以会出现重复计算的情况。经过优化后可以通过,大大缩短运行时间,优化后的方法就是第二种思路方法

⏳题目代码   

 /*
    给定一个二叉树,判断它是否是平衡二叉树
    平衡二叉树 :是指该树所有节点的左右子树的深度相差不超过1。
    */
  public boolean isBalanced(BTNode root) {
            if(root==null)
                return true;
            int a=getHeight(root.left);
            int b=getHeight(root.right);
            return  Math.abs(a-b)<=1 && isBalanced(root.left)&&isBalanced(root.right);
        }
    int getHeight(BTNode root) {
        int height = 0;
        if (root == null)
            return 0;
        return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
    }

6.2第二种思路 

 📋题目思路 

具体实现过程如下

首先,判断二叉树是否为空。若为空,则认为其是平衡的,返回 true。否则,调用 getHeight() 函数计算二叉树的高度。

getHeight() 函数递归地计算二叉树的高度。若当前节点为空,则返回 0。否则,分别递归计算左右子树的高度,并判断其高度差是否小于等于 1。若满足条件,则返回左右子树中更高的高度加一。否则,返回 -1,表示当前子树不平衡。

如果返回出的二叉树高度大于0,则认为是平衡的;否则认为是不平衡的。

第二种思路相比第一种思路其运行时间大大缩短了,可以说比第一种思路更好,直接一次遍历就实现了效果。

⏳题目代码    

  //给定一个二叉树,判断它是否是平衡二叉树.(进阶版,更加高效)
 public boolean isBalanced(BTNode root) {
               if(root==null)
                   return  true;
               if(getHeight(root)>0)
                   return  true;
               else
                   return  false;
    }

    public  int getHeight(BTNode root){
        if(root==null)
            return  0;
        int a=getHeight(root.left);
        if(a<0)
            return -1;
        int b=getHeight(root.right);
        if(b<0)
            return -1;
        if(Math.abs(a-b)<=1)
            return  Math.max(a,b)+1;
        else
            return  -1;
    }
}

该题链接:判断一颗二叉树是否是平衡二叉树  


7.二叉树的构建及遍历 

📌题目描述 

编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储), 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。


 📋题目思路 

这题比较难,我们讲的细致些,并且对于该题没有帮我们自动实现内部类,我们需要自己去实现。以下是对这段代码的详细讲解:

  类和成员变量

public class Main{
    public int i; // 用于追踪当前处理的字符位置
    static class BTNode{
        char value; // 节点的值
        BTNode left; // 左子节点
        BTNode right; // 右子节点

        public BTNode(char value) {
            this.value = value;
        }
    }
}
  • Main类包含一个成员变量i,用于记录当前处理的字符位置。
  • BTNode是一个静态内部类,表示二叉树的节点。每个节点包含一个字符值(value),一个指向左子节点的指针(left),和一个指向右子节点的指针(right)。

  主函数

public static void main(String[] args) {
    Scanner in = new Scanner(System.in);

    // 注意 hasNext 和 hasNextLine 的区别
    while (in.hasNextLine()) { // 注意 while 处理多个 case
        Main main = new Main(); // 为每行输入创建一个新的Main对象
        String b = in.nextLine(); // 读取一行输入
        BTNode root = main.creatBinaryTree(b); // 构建二叉树
        main.inOrder(root); // 对构建的二叉树进行中序遍历
        System.out.println(); // 输出完一行后换行
    }
}
  • 主函数使用Scanner对象从标准输入中读取用户输入的字符串。
  • while (in.hasNextLine())循环可以处理多行输入。
  • 对于每一行输入,创建一个新的Main对象并调用creatBinaryTree方法构建二叉树,然后调用inOrder方法进行中序遍历并输出结果。

 构建二叉树

public BTNode creatBinaryTree(String s){
    if (i >= s.length()) {
        return null;
    }
    if (s.charAt(i) == '#') {
        return null;
    }
    BTNode root = new BTNode(s.charAt(i)); // 创建根节点
    i++;
    root.left = creatBinaryTree(s); // 递归构建左子树
    i++;
    root.right = creatBinaryTree(s); // 递归构建右子树
    return root;
}
  • creatBinaryTree方法通过递归的方式根据前序遍历字符串构建二叉树。
  • 如果当前字符是#,表示当前节点为空,返回null
  • 否则,创建一个新节点,并递归构建左子树和右子树。
  • 需要注意的是,i在递归调用前后都会自增,以确保处理下一个字符。

中序遍历

public void inOrder(BTNode root){
    if (root == null)
        return;
    inOrder(root.left); // 递归遍历左子树
    System.out.print(root.value + " "); // 打印当前节点的值
    inOrder(root.right); // 递归遍历右子树
}
  • inOrder方法通过递归的方式进行中序遍历。
  • 如果当前节点为空,直接返回。
  • 先递归遍历左子树,再打印当前节点的值,最后递归遍历右子树。

代码中的潜在问题

  1. i的初始值i应该在每次构建新树前初始化为0,以确保从字符串的开始位置处理。所以我们将i设置为实例成员变量,这样每次创建新树时i初始值都是0。.
  2. 字符串边界检查:在访问字符串字符前需要检查索引是否越界,一般我们输入的字符串都是合法的,不会发生越界情况。

 ⏳题目代码    

/*编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。
     例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。
     建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。*/
public class Main{
    public   int i;
    static class BTNode{
        char value;
        BTNode left;
        BTNode right;

        public BTNode(char value) {
            this.value = value;
        }
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
             Main main=new Main();
            String b = in.nextLine();
         BTNode root =  main.creatBinaryTree(b);
            main.inOrder(root);
        }
    }
    public  BTNode creatBinaryTree(String s){
        if(s.charAt(i)=='#')
         return  null;
       BTNode root  =new BTNode(s.charAt(i));
               i++;
       root.left= creatBinaryTree(s);
              i++;
         root.right=creatBinaryTree(s);
         return root;
    }
    public void inOrder( BTNode root){
        if(root==null)
            return;
        inOrder(root.left);
        System.out.print(root.value+" ");
        inOrder(root.right);
    }


}

该题链接:二叉树的构建及遍历 


8.总结

这篇文章讲了6个二叉树习题,下篇文章将会继续讲二叉树的相关习题。在此,我们诚挚地邀请各位大佬们为我们点赞、关注,并在评论区留下您宝贵的意见与建议。让我们共同学习,共同进步,为知识的海洋增添更多宝贵的财富!🎉🎉🎉❤️❤️💕💕🥳👏👏👏

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

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

相关文章

语音群呼之语音导航的应用

在数字化时代&#xff0c;语音群呼技术已成为企业、组织和个人高效沟通的重要工具。语音群呼不仅能够快速地将信息传递给目标群体&#xff0c;而且通过语音导航功能&#xff0c;还能确保信息传达的准确性和用户体验的优质性。本文将深入探讨语音群呼的语音导航功能&#xff0c;…

HTML:认识HTML与基本语法的学习

前言 HTML&#xff08;超文本标记语言&#xff09;是用于创建网页的标记语言&#xff0c;由一系列标签组成&#xff0c;定义网页中的元素。由蒂姆伯纳斯 - 李于1990年代初发明&#xff0c;最初用于科研机构间共享文档&#xff0c;迅速演变为Web开发基础。无论是电商、博客、新…

一条sql的执行流程

文章地址 https://blog.csdn.net/qq_43618881/article/details/118657040 连接器 请求先走到连接器&#xff0c;与客户端建立连接、获取权限、维持和管理连接 mysql缓存池 如果要查找的数据直接在mysql缓存池里面就直接返回数据 分析器 请求已经建立了连接&#xff0c;现在…

串联式固定测斜仪无需钢丝绳、安装方便、可回收利用边坡基坑矿山地灾常用

一、固定式测斜仪的简介 固定测斜仪是一种用于长期自动监测各种结构物的深层水平位移的设备&#xff0c;获取土体内部的位移变化趋势&#xff0c;监测数据上传至安锐测控云平台&#xff0c;用户即可实时查看结构深层水平位移数据&#xff0c;实时预警&#xff0c;保障结构的安全…

代码随想录算法训练营第四十八 | ● 121. 买卖股票的最佳时机 ● 122.买卖股票的最佳时机II

121. 买卖股票的最佳时机 买卖股票的最佳时机 视频讲解&#xff1a;https://www.bilibili.com/video/BV1Xe4y1u77q https://programmercarl.com/0121.%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BA.html class Solution { public:int ma…

自友科技破解走班教育排课难题

新高考后&#xff0c;校园教务都面临着晋级&#xff0c;其中走班教育的分班排课是个巨大的挑战。 所以在分班排课的时候要清楚一下几个问题 一是&#xff1a;清楚的核算学生的选考科目。学生选科提交后做好并承认&#xff0c;最好是在分班后不要改或很少的一部分人改动。 二是…

世净超声波清洗机怎么样?美的、希亦、世净超声波清洗机谁更值得买?

在日常生活和专业领域中&#xff0c;清洁工作往往是既重要又烦琐的任务。特别是对于那些难以手工得尤为重要。关键是现在超声波清洗机已经不是从前的超声波清洗机了&#xff0c;不是只在工业领域上清洗一些重大零件了&#xff0c;已经逐渐开始能够清洗日常物品&#xff0c;像眼…

重庆工商大学社会工作专业试题及答案,分享几个实用搜题和学习工具 #媒体#学习方法#知识分享

搜题软件一般都是通过识别题目内容搜索出问题的答案&#xff0c;当识别内容不正确或搜索不到答案时&#xff0c;又得重新到其他软件进行重复的操作&#xff0c;很是麻烦。所以我们可以使用专业的识别工具&#xff0c;对题目内容进行识别&#xff0c;然后把提取出来的内容单独保…

【MySQL数据库】my.ini文件参数中文注释

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主。 &#x1f913; 同时欢迎大家关注其他专栏&#xff0c;我将分享Web前后端开发、人工智能、机器学习、深…

Qsemaphore

Qsemaphore 实现 给while循环阻塞延时 基本思路就是&#xff1a; whlie循环里面 通过m&#xff3f;bthreadFlag&m_bStatus这两个标志位&#xff0c;判断是否进入while循环&#xff0c;再根据40行的acquire&#xff08;&#xff09;来阻塞循环&#xff0c;因为定时器的槽函数…

VCS基本仿真

这里记录三种仿真方式&#xff1a; 第一种是将verilog文件一个一个敲在终端上进行仿真&#xff1b; 第二种是将多个verilog文件的文件路径整理在一个文件中&#xff0c;然后进行仿真&#xff1b; 第三种是利用makefile文件进行仿真&#xff1b; 以8位加法器为例&#xff1a; …

13、SpringBoot 源码分析 - 自动配置深度分析六

SpringBoot 源码分析 - 自动配置深度分析六 refresh和自动配置大致流程AutoConfigurationImportSelector的fireAutoConfigurationImportEvents通知自动配置导入事件AutoConfigurationGroup的selectImports封装成Entry返回MyAutoConfiguration自动配置类创建META-INF文件夹和文件…

js解析成语法树以及还原

const {parse} require("babel/parser"); const traverse require("babel/traverse").default; const generator require("babel/generator").default;// 1.定义要处理的代码 const jscode function square(n) {return n * n; };// 2.使用ba…

c++ EECS280

Introduction Euchre (pronounced “YOO-kur”) is a card game popular in Michigan. The learning goals of this project include Abstract Data Types in C, Derived Classes, Inheritance, and Polymorphism. You’ll gain practice with C-style Object Oriented Progr…

104、二叉树的最大深度

给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 题解&#xff1a;所谓深度&#xff0c;就是树中某节点距离根节点的距离&#xff0c;如图中根节点3的深度为1&#xff0c;那节点7的深度为3&#x…

人类语言处理nlp部分笔记——二、BERT和它的家族-介绍和微调

参考自李宏毅课程-人类语言处理 二、BERT和它的家族-介绍和微调 1. What is pre-train model 这里所说的pre-train model是输入一串tokens&#xff0c;能够输出一串vectors&#xff0c;且每个vector可以表示对应的语义的模型&#xff0c;这些vectors也被称作为embeddings。以…

NXdfefefef

prototype&#xff1a;原型 CORS(Cross-Origin Resource Sharing):跨资源共享 Interceptor&#xff1a;拦截器 BOM&#xff1a;Browser Object Module(浏览器对象模型) Ajax(Asynchronous Javascript And XML)&#xff1a;异步的JavaScript和XML&#xff0c;Ajax其实就是浏览器…

apifox 生成签名

目录 前言准备编写签名脚本签名说明捋清思路编码获取签名所需的参数生成签名将签名放到合适的位置完整代码 在apifox中配置脚本新增公共脚本引用公共脚本添加环境变量 参考 前言 略 准备 查看apifox提供的最佳实践文章&#xff1a;接口签名如何处理 编写签名脚本 签名说明…

NineData蔡冬者参与编写墨天轮《2023年中国数据库行业年度分析报告》正式发布!

为明晰发展脉络&#xff0c;把握未来趋势&#xff0c;墨天轮于5月29日正式发布 《2023年中国数据库年度行业分析报告》。该报告由墨天轮联合业界专家学者共同编写&#xff0c;共330页&#xff0c;旨在梳理和洞察中国数据库行业的发展趋势、技术创新、市场动态以及面临的挑战&am…

不讲废话,热门主食冻干鲜朗、希喂、生生不息横向分析

随着科学养宠的普及&#xff0c;主食冻干喂养成为了新的流行趋势。除了知名的“四大金刚”K9、VE、SC、PR外&#xff0c;希喂、鲜朗等新兴品牌也以其营养和高肉含量的特点&#xff0c;获得了消费者的青睐。各大猫粮厂商也看准了这一市场机遇&#xff0c;纷纷推出了自家的主食冻…