二叉树的各类实现判断二叉树的递归套路

news2024/12/28 19:57:04

如何判断一颗二叉树是否是搜索二叉树? 

搜索二叉树

每个子树头节点的左孩子比它小,右孩子比它大

经典的搜索二叉树没有重复的数

判断

将二叉树按照中序遍历,判断是否为升序

1、先将整棵树中序遍历再判断是否升序
    //中序遍历
    public static ArrayList<Node> traverse_medium(Node node) {
        if (node == null) {
            return null;
        }

        ArrayList<Node> list = new ArrayList<>();

        traverse_medium(node.left);
        //输出改为存储入集合之中
        list.add(node);
        traverse_medium(node.right);

        return list;
    }

    //判断搜索二叉树
    public static boolean is_bst_one(ArrayList<Node> list) {
        for (int i = 0; i < list.size() - 2; i++) {
            if (list.get(i).value >= list.get(i + 1).value) {//这里认为等于不可行
                return false;
            }
        }
        return true;
    }
2、在中序遍历的过程中判断是否升序
        (1) 使用递归的中序遍历
    //判断搜索二叉树
    public static boolean is_bst_two1(Node node) {
        if (node == null) {
            return true;//认为空二叉树是搜索二叉树
        }

        int preValue = Integer.MIN_VALUE;

        //判断左子树是否为搜索二叉树
        boolean isLeftBst = is_bst_two1(node.left);

        //中序遍历的第二轮,输出改为判断
        //如果左树不是搜索二叉树,那么整棵树一定不是搜索二叉树
        if (!isLeftBst) {
            return false;
        }
        if (node.value > preValue) {
            preValue = node.value;//递归逐层向下找,会最先找到最左侧的节点,逐层向上比较,preValue逐层向上赋值
        } else {//node.value <= preValue,不满足搜索二叉树条件
            return false;
        }

        //在左子树为搜索二叉树的前提下,如果右子树为搜索二叉树,那么整棵树一定都是搜索二叉树
        return is_bst_two1(node.right);
    }
        (2)不使用递归的中序遍历 
    //判断搜索二叉树
    public static boolean is_bst_two2(Node node) {
        if (node == null) {
            return true;//认为空二叉树是搜索二叉树
        }

        int preValue = Integer.MIN_VALUE;

        Stack<Node> stack = new Stack<Node>();
        while (!stack.isEmpty() || node != null) {
            if (node != null) {
                stack.push(node);
                node = node.left;//整个左子树入栈
            } else {
                node = stack.pop();//出栈

                //输出变为比较
                if (node.value <= preValue) {//不满足条件
                    return false;
                } else {//node.value > preValue,满足条件
                    preValue = node.value;//preValue逐层向上
                }

                node = node.right;//如果右节点为null则弹出下一个,如果不为null则将右节点弹入栈
            }
        }
        return true;
    }

如何判断一颗二叉树是否是完全二叉树? 

完全二叉树

二叉树从左向右依次变满(左图为满二叉树,右图为普通的完全二叉树)

          

判断

二叉树按宽度遍历

条件1:如果某一个子树的头节点有右孩子没有左孩子,返回false

条件2:在条件1的前提下,如果有一个节点左右孩子不双全,后续的节点都是叶节点(它右侧的所有节点都没有子节点)

    //判断完全二叉树
    public static boolean isCBT(Node node) {
        if (node == null) {
            return true;//空二叉树认为是完全二叉树
        }

        boolean notBoth = false;//记录是否遇到不双全的节点
        Node left = null;
        Node right = null;

        Queue<Node> queue = new LinkedList<>();
        queue.add(node);

        while (!queue.isEmpty()) {
            Node node0 = queue.poll();

            if ((left == null && right != null)//不满足条件1:左节点null且右节点不为null
                    || (notBoth && (left != null || right != null))) {//不满足条件2:遇到不双全的节点但后面的节点不为叶节点
                return false;
            }
            
            if (node0.left != null) {
                queue.add(node0.left);//先右节点入队列
            }
            if (node0.right != null) {
                queue.add(node0.right);//再左节点入队列
            }

            if (left == null || right == null) {//不双全的节点
                notBoth = true;
            }
        }
        return true;
    }

如何判断一颗二叉树是否是满二叉树? 

满二叉树

相关题目

求二叉树的最大深度或节点个数

已知最大深度为max,则节点个数  N = 2^{^{max}} - 1

二叉树的递归套路判断是否为满二叉树

这里可以先看下面的递归套路再理解如何用套路求是否为满二叉树

递归套路:返回二叉树的最大深度,节点个数

在调用的函数中判断是否满足满二叉树的条件

package binarytree;

public class IsFullBinaryTree {

    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }


    public boolean isFullBinaryTree(Node node) {
        return process(node).nodeNumber == Math.pow(2,process(node).depth) - 1;//nodeNumber是否等于2的depth次方-1
    }

    //所需要的信息:返回二叉树的最大深度,节点个数
    public static class Message {
        public int depth;
        public int nodeNumber;

        public Message(int depth, int nodeNumber) {
            this.depth = depth;
            this.nodeNumber = nodeNumber;
        }
    }


    public Message process(Node node) {
        if (node == null) {
            return null;
        }

        Message leftMessage = process(node.left);
        Message rightMessage = process(node.right);

        int depth = Math.max(leftMessage.depth, rightMessage.depth) + 1;//最大深度要加上当前的节点这一层
        int nodeNumber = leftMessage.nodeNumber + rightMessage.nodeNumber + 1;//节点个数=左子树节点个数+右子树节点个数

        return new Message(depth, nodeNumber);
    }
}

如何判断一颗二叉树是否是平衡二叉树? 

平衡二叉树

左子树与右子树的高度差不超过1

二叉树的递归套路

        问左树要的信息:左树是否是平衡二叉树;左树的高度

        问右树要的信息:右树是否是平衡二叉树;右树的高度

递归函数:返回是否为平衡二叉树,二叉树的深度

package binarytree;

public class IsBalancedBinaryTree {
    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }


    public boolean isBalancedBinaryTree(Node node) {
        return process(node).isBalance;
    }

    //所需要的信息:返回是否为平衡二叉树,二叉树的深度
    public static class Message {
        public boolean isBalance;
        public int depth;

        public Message(boolean isBalanced, int depth) {
            this.isBalance = isBalance;
            this.depth = depth;
        }
    }


    public Message process(Node node) {
        if (node == null) {
            return null;
        }

        Message leftMessage = process(node.left);//左边的信息
        Message rightMessage = process(node.right);//右边的信息

        int depth = Math.max(leftMessage.depth, rightMessage.depth) + 1;//最大深度要加上当前的节点这一层
        boolean isBalanced = leftMessage.isBalance && rightMessage.isBalance
                && (Math.abs(leftMessage.depth - rightMessage.depth) <= 1);
        //左右都为平衡二叉树并且左右子树深度差不超过1

        return new Message(isBalanced, depth);
    }
}

二叉树的递归套路

在文章中判断二叉树是否为完全二叉树/满二叉树/平衡二叉树等等的题型,都可以抽象出一个二叉树的递归套路

递归套路

树型DP问题(树上动态规划)可以用二叉树的递归套路来解

这里用文档注释表示具体需要写的代码

package binarytree;

public class Template {

    //Node类,节点
    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }

    //最终调用的函数,返回最后的结果
    public boolean judgment(Node node) {
        return true;//一般调用process函数获得Message对象,再获取Message对象里的信息
    }

    //Message类,信息
    //所需要的信息
    public static class Message {
        /*
        定义属性
         */

        //定义构造器
        public Message() {

        }
    }

    //具体的遍历过程
    public Message process(Node node){
        if (node == null) {
            return null;
        }
        
        Message leftMessage = process(node.left);//左边的信息
        Message rightMessage = process(node.right);//右边的信息
        
        /*
        具体判断具体分析,根据左右子树的属性获取总的这颗树的属性
         */
        
        //创建Message对象,把获取的属性赋值给新的属性,并返回
        return new Message();
    }
}

二叉树的递归套路解判断是否为搜索二叉树

        问左树要的信息:左树是否为搜索二叉树;左树的最大值(左树max < 当前节点的值)

        问右树要的信息:右树是否为搜索二叉树;右树的最小值(右树min > 当前节点的值)

递归函数:返回是否为搜索二叉树,二叉树的最大值,最小值

package binarytree;

public class IsSearchBinaryTree {

    public static class Node {
        public int value;
        public Node left;
        public Node right;

        public Node(int data) {
            this.value = data;
        }
    }


    public boolean isSearchBinaryTree(Node node) {
        return process(node).isSearch;
    }

    //所需要的信息:返回是否为搜索二叉树,二叉树的最大值,最小值
    public static class Message {
        public boolean isSearch;
        public int max;
        public int min;

        public Message(boolean isSearch, int max, int min) {
            this.isSearch = isSearch;
            this.max = max;
            this.min = min;
        }
    }


    public Message process(Node node){
        if (node == null) {
            return null;
        }

        Message leftMessage = process(node.left);//左边的信息
        Message rightMessage = process(node.right);//右边的信息

        int max = Math.max(leftMessage.max, rightMessage.max);
        max = Math.max(max,node.value);//当前节点和左右节点的值比较得出最大值
        int min = Math.min(leftMessage.min, rightMessage.min);
        min = Math.min(min,node.value);

        boolean isSearch = leftMessage.isSearch && rightMessage.isSearch
                && leftMessage.max < node.value && rightMessage.min > node.value;
        //左右子树都为搜索二叉树,左子树max < 当前节点的值 < 右子树min;暂不考虑等于的情况

        return new Message(isSearch,max,min);
    }
}

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

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

相关文章

如何获取ABAP的程序事件顺序的调用堆栈

难道有激情总结下之前做过的事情&#xff0c;话不多说直接上图 重点在于此函数 CALL FUNCTION SYSTEM_CALLSTACK IMPORTING ET_CALLSTACK L_CSTACK_TAB. " internal table

AD9371 官方例程HDL详解之JESD204B TX侧时钟生成 (一)

AD9371 系列快速入口 AD9371ZCU102 移植到 ZCU106 &#xff1a; AD9371 官方例程构建及单音信号收发 ad9371_tx_jesd -->util_ad9371_xcvr接口映射&#xff1a; AD9371 官方例程之 tx_jesd 与 xcvr接口映射 梳理 AD9371 时钟&#xff0c;理解采样率和各个时钟之间的关系 …

【WCA-KELM预测】基于水循环算法优化核极限学习机回归预测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

详解Windows系统下面如何查看CUDA、cuDNN、Python和各个软件包的版本

文章目录 简介查看CUDA版本查看cuDNN版本查看Python版本查看Python环境中已安装软件包的版本参考 简介 这个题目网络上有很多的讲解&#xff0c;但是查看CUDA、cuDNN版本和查看Python与自身各个软件包是分开的&#xff0c;且cuDNN版本的查看方式似乎已经过时【截止2023-10-23】…

测试面试必备:HTTP请求和响应详解!

一次完整的HTTP请求过程从TCP三次握手建立连接成功后开始&#xff0c;客户端按照指定的格式开始向服务端发送HTTP请求&#xff0c;服务端接收请求后&#xff0c;解析HTTP请求&#xff0c;处理完业务逻辑&#xff0c;最后返回一个HTTP的响应给客户端&#xff0c;HTTP的响应内容同…

Windows新电脑安装环境快速运行Springboot项目

文章目录 简要步骤说明1、配置java运行环境2、配置maven环境3、下载git4、运行IDES Eclipse STS4.1 安装 lombok插件4.2 配置 maven setting.xml 地址4.3 配置 Java版本 5、顺利运行 Springboot项目 简要步骤说明 1、配置java运行环境 安装java11 2、配置maven环境 配置 setti…

【c++】遍历容器,哪一种方法速度最快?

终于有一个简单的每日一题&#xff01;写完的时候甚至代码还没有编译结束&#xff01;刚好借今天的每日一题探究一下一直以来的一些疑惑&#xff1a;容器的遍历。 题目大概是这样的&#xff1a; 我们一眼就看到了容器的遍历&#xff01;&#xff01;那么众所周知&#xff0c;容…

管理类联考——英语二——阅读篇——题材:经济

文章目录 2011 年&#xff0c;Text 2——题材&#xff1a;经济句意理解题-原词复现一般不选&#xff0c;但是要留意无中生有推断题-原词复现&#xff0c;注意是否“无中生有”“对象错误”“词意相反”推断题推断题主旨题-不了解阅读意思&#xff0c;很难做出选择 2011 年&…

R-CNN(CVPR2014)

文章目录 AbstractIntroductionObject detection with R-CNNModule designTest-time detection Visualization, ablation, and modes of errorSemantic segmentationConclusion 论文链接 源代码 Abstract 在经典PASCAL VOC数据集上测量的对象检测性能在过去几年中趋于稳定&…

MTK6737安卓核心板-MT6737核心板_4G安卓模块

MT6737核心板以竞争力的价格提供出色的性能和功耗效率&#xff0c;降低了BOM、GMO和内存成本&#xff0c;符合以价值为导向的市场需求。该核心板是一种先进的解决方案&#xff0c;为终端用户提供了高品质又经济实惠的体验。它与全球范围内的IMS兼容&#xff0c;支持VoLTE、ViLT…

【C++那些事儿】函数重载与C++中的“指针“——引用

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;我之前看过一套书叫做《明朝那些事儿》&#xff0c;把本来枯燥的历史讲的生动有趣。而C作为一门接近底层的语言&#xff0c;无疑是抽象且难度颇…

SparkSQL之LogicalPlan概述

逻辑计划阶段在整个流程中起着承前启后的作用。在此阶段&#xff0c;字符串形态的SQL语句转换为树结构形态的逻辑算子树&#xff0c;SQL中所包含的各种处理逻辑&#xff08;过滤、剪裁等&#xff09;和数据信息都会被整合在逻辑算子树的不同节点中。逻辑计划本质上是一种中间过…

面试时一些不能说的离职原因

“你为什么从上一家公司离职&#xff1f;”这个问题在面试时基本都会被问到&#xff0c;这是无法避免的问题。那么什么样的理由才能做到既反映实际情况&#xff0c;又能得到HR认可呢&#xff1f;以下的几种回答千万不能脱口而出。 1、毫无顾忌地说前公司的坏话 1&#xff09;…

进阶JAVA篇- Map 系列集合的遍历方法与常用API

目录 1.0 Map 集合的说明 1.1 Map 集合的常用方法 1.2 Map 系列集合的特点 2.0 Map 系列集合的遍历方法&#xff08;三种方法&#xff09; 2.1 使用 keySet() 方法遍历 2.2 使用 entrySet() 方法遍历 2.3 使用 forEach() 方法遍历&#xff08;Java 8&#xff09; 1.0 Map 集合的…

数据结构与算法——选择排序法

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

镇魂街武神躯手游攻略,镇魂街武神躯神魂搭配

武神躯是《镇魂街》手游中令人敬畏的角色之一&#xff0c;技能的合理搭配至关重要。下面将详细介绍镇魂街武神躯手游攻略如何搭配武神躯的技能以取得最佳战斗效果&#xff1a; 关注【娱乐天梯】&#xff0c;获取内部福利号 1. 主动技能-刺客之心&#xff1a;这是武神躯的核心主…

python 桌面软件开发-matplotlib画图鼠标缩放拖动

继上一篇在 Java 中缩放拖动图片后&#xff0c;在python matplotlib中也来实现一个自由缩放拖动的例子&#xff1a; python matplotlib 中缩放&#xff0c;较为简单&#xff0c;只需要通过设置要显示的 x y坐标的显示范围即可。基于此&#xff0c;实现一个鼠标监听回调&#xf…

python安装的第三方库

安装第三方库的方式 先按“winR”并输入 cmd 打开命令运行窗口 输入命令&#xff1a; pip install 包名&#xff0c;比如要安装gym包就输入pip install gym 可能存在报错问题及解决办法 报错Could not fetch URL https://pypi.tuna.tsinghua.edu.cn/simple/pip/: There was …

基于Java的美食推荐管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

SparkSQL的Shuffle分区设定及异常数据处理API(去重、缺失值处理)

一、Spark SQL的Shuffle分区数目设定 在允许spark程序时&#xff0c;查看WEB UI监控页面发现&#xff0c;某个Stage中有200个Task任务&#xff0c;也就是说RDD有200分区Partion。 产生原因&#xff1a; 在Spark SQL中&#xff0c;当Job中产生Shuffle时&#xff0c;默认的分区数…