【Java】—— 二叉树

一、树型结构

        

        树形结构是一种重要的数据结构,它类似于现实生活中的树的结构,由结点和边构成。树形结构具有以下特点:

  1. 树形结构是一种层次化的结构,由根结点、内部结点和叶子结点组成。
  2. 根结点是树的顶部结点,没有父结点,所有其他结点都是它的后代。
  3. 内部结点是除根结点外的其他非叶子结点,它们至少有一个子结点。
  4. 叶子结点是没有子结点的结点,位于树的底部。
  5. 子树之间不能有交集,否则就不是树形结构
  6. 结点之间通过边相连,表示结点之间的关系。

        树形结构常用于表示层次关系、分类结构、组织结构等。在计算机科学中,树形结构也广泛应用于数据存储、算法设计等方面,例如二叉树、二叉搜索树、堆等都是基于树形结构设计的数据结构。树形结构的灵活性和高效性使其成为计算机科学中一种非常重要的数据结构。

二、二叉树

1、二叉树的定义

        二叉树是一种树状数据结构,其中每个节点最多有两个子结点,通常称为左子结点和右子结点。二叉树具有以下特点:

  1. 每个结点最多有两个子结点,分别为左子结点和右子结点。
  2. 左子结点和右子结点可以为空,也可以是叶子结点(没有子节点的结点)。
  3. 二叉树具有递归的定义,即每个结点的左子树和右子树都是二叉树。

二叉树的结点包括一个数据域和指向左子结点和右子结点的指针域。在实际应用中,二叉树常用于表示层次关系、树状结构等。

2、二叉树的特性

  1. 二叉树不存在子结点数量大于 2 的情况
  2. 二叉树的子结点有左右之分,次序不能颠倒,因此二叉树是有序树
  3. 左子树和右子树也是二叉树,它们可以为空。
  4. 二叉树的结点之间通过边相连,且不存在环路。
  5. 二叉树的深度(或高度)是从根节点到叶子节点的最长路径上的节点数。

3、两种特殊的二叉树

满二叉树:一棵二叉树,如果每层的结点数都达到最大值(层数为k,结点总数是2^{k-1}),那么这棵二叉树就是满二叉树

完全二叉树:完全二叉树是效率很高的数据结构,是由满二叉树而引出来的。

对于深度为 k 的,有 n 个结点的二叉树,当且仅当每一个节点都与深度为 k 的满二叉树中编号从 0 至 n-1 的结点一一对应时称之为完全二叉树

满二叉树是一种特殊的完全二叉树

4、二叉树的存储

孩子表示法

class Node {
    int val;    //树中存储的数据
    Node left;    //左子结点,可以代表左子树为根的整棵左子树
    Node right;   //右子结点,可以代表右子树为根的整棵右子树
}

孩子双亲表达法

class Node {
    int val;    //树中存储的数据
    Node left;    //左子结点,可以代表左子树为根的整棵左子树
    Node right;   //右子结点,可以代表右子树为根的整棵右子树
    Node parent;    //当前结点的根结点
}

还有许多表达法,这里不再一一介绍

5、创建一棵树

class Node {
    public String val;    //树中存储的数据
    public Node left;    //左子结点,可以代表左子树为根的整棵左子树
    public Node right;   //右子结点,可以代表右子树为根的整棵右子树
    public Node(String val){
        this.val = val;
        this.left = null;
        this.right = null;
    }
}
//可以通过一个根结点拿到整个树
//还可以通过创建一个新的类,在类中持有上述的 Node root
class Tree{
    public Node root;
}


public class text1 {
    public static Node creatTree(){
        //创建出所有的节点
        Node a = new Node("A");
        Node b = new Node("B");
        Node c = new Node("C");
        Node d = new Node("D");
        Node e = new Node("E");
        Node f = new Node("F");
        Node g = new Node("G");

        //把这些节点连起来
        a.left = b;
        a.right = c;
        b.left = d;
        b.right = e;
        c.right = f;
        e.left = g;

        //返回根结点
        return a;
    }
    public static void main(String[] args) {
        //第一种写法,在笔试面试中比较常见
        Node root = new Node("A");
        //第二钟写法,在工作中比较常见
        Tree tree = new Tree();
    }
}

 6、树的遍历

二叉树的本身就是递归定义的结构,所以二叉树的遍历也是基于递归,有四种的遍历方法,分别是 先序 、中序 、后序 、层序。接下来分别演示对下图二叉树的不同遍历

先序(第一个是根节点)

    //先序
    public static void preOrder(Node root){
        //1.如果为null说明是空树,直接返回
        if(root == null){
            return;
        }
        //2.先打印,再进子节点
        System.out.print(root.val + " ");
        preOrder(root.left);
        preOrder(root.right);
    }

中序(遍历结果中,根节点左侧的就是左子树,根节点右侧的就是右子树)

    //中序
    public static void inOrder(Node root){
        //1.如果为null说明是空树,直接返回
        if(root == null){
            return;
        }
        //2.进左子节点后打印再进右子节点
        inOrder(root.left);
        System.out.print(root.val + " ");
        inOrder(root.right);
    }

后序(最后一个元素是根节点)

    //后序
    public static void postOrder(Node root){
        //1.如果为null说明是空树,直接返回
        if(root == null){
            return;
        }
        //2.进完两个子节点后再打印
        inOrder(root.left);
        inOrder(root.right);
        System.out.print(root.val + " ");
    }

层序(按照层次,把每一层的元素从左到右访问出来)

层序遍历的实现,需要搭配一个队列 

    //层序
    public static void levelOrder(Node root){
        if(root == null){
            return;
        }
        //创建一个队列,辅助层序进行遍历
        Queue<Node> queue = new LinkedList<>();
        //把根节点添加到队列中
        queue.offer(root);
        //如果队首不为空
        while (!queue.isEmpty()){
            //取出队首元素
            Node cur = queue.poll();
            //打印
            System.out.print(cur.val + " ");
            //把队首的左右节点加入队列
            if(cur.left != null){
                queue.offer(cur.left);
            }
            if(cur.right != null){
                queue.offer(cur.right);
            }
        }
    }

7、二叉树的基本操作

7.1 求二叉树节点个数

    //求二叉树的节点个数
    public static int size(Node root){
        if(root == null){
            return 0;
        }
        //递归过程中把子树递归的结果返回上层方法中
        //1 是当前节点不为空的返回值,
        return 1 + size(root.left) + size(root.right);
    }

7.2 求二叉树叶子结点个数

    //求二叉树叶子结点的个数
    public static int getLeafSize(Node root){
        if(root == null){
            return 0;
        }
        //两个子节点都为 null 就是叶子结点
        if( root.left == null && root.right == null){
            return 1;
        }
        //如果当前节点不是叶子结点就递归的求左、右子节点
        return  getLeafSize(root.left) + getLeafSize(root.right);
    }

7.3 求 k 层节点个数

    //求 k 层节点的个数
    public static  int getKLevelNodeCount(Node root,int k){
        if(root == null || k < 1){
            return 0;
        }
        //根节点
        if(k==1){
            return 1;
        }
        return getKLevelNodeCount(root.left,k-1) + getKLevelNodeCount(root.right,k-1);
    }

7.4 获取二叉树的高度

    //求二叉树的最大高度
    public static int bestHigh(Node root){
        if(root == null){
            return 0;
        }
        return Math.max(bestHigh(root.left),bestHigh(root.right))+1;
    }

7.5 查找 val 值是否存在

    //查找元素是否存在
    public static Node find(Node root,String val){
        if(root == null){
            return null;
        }
        if(root.val.equals(val)){
            return root;
        }
        //递归查找左侧子树
        Node leftResult = find(root.left,val);
        if(leftResult != null){
            //找到了直接返回结果
            return leftResult;
        }
        //没找到就到右子树查找
        Node rightResult = find(root.right,val);
        if(rightResult != null){
            return rightResult;
        }
        //最后没找到直接返回null 
        return null;
    }

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

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

相关文章

AWS - Redshift - 外部表读取 Parquet 文件中 timestamp 类型的数据

问题&#xff1a; 通过 Redshift Spectrum 功能可以读取 S3 中的文件&#xff0c;当读取 Parquet 文件时&#xff0c;如果列格式设置为 timestamp&#xff0c; 通过 psql 客户端读取会出现以下错误&#xff1a; testdb# select * from myspectrum_schema_0219.test_ns; ERROR…

即插即用Transformer、扩散模型、机器人规划、长文本检索增强生成 | Big Model Weekly 第57期...

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 01 ProTransformer: Robustify Transformers via Plug-and-Play Paradigm 近年来&#xff0c;基于Transformer的架构在机器学习的各个领域占据了主导地位。本文介绍了一种新颖的鲁棒性注意力机制&#xff0c;旨…

[ComfyUI] 【AI】如何获得一张人物图片的优质描述

在使用ComfyUI时,获取一张人物图片的优质英文描述非常重要,尤其是在涉及图像生成、自动化标签和多模态AI任务时。以下是一个简单的流程,可以帮助你快速从一张人物图片中提取出精确且高质量的英文描述。 1. 打开 Hugging Face 网站 首先,您需要访问 Hugging Face 提供的 J…

DeepSeek-R1:通过强化学习激励大语言模型的推理能力

摘要 本文介绍了我们的第一代推理模型&#xff0c;DeepSeek-R1-Zero 和 DeepSeek-R1。DeepSeek-R1-Zero 是通过大规 模强化学习&#xff08;RL&#xff09;训练的模型&#xff0c;在没有使用监督微调&#xff08;SFT&#xff09;这个前置步骤的情况下&#xff0c;展示了卓越的推…

springboot004网页时装购物系统(源码+数据库+文档)

源码地址&#xff1a;网页时装购物系统 文章目录 1.项目简介2.部分数据库结构与测试用例3.系统功能结构4.包含的文件列表&#xff08;含论文&#xff09;前台运行截图后台运行截图 1.项目简介 ​ 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的…

C++ Primer 容器适配器

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

git上传gitee仓库---简单方便

安装完git以后 在资源管理器中右键&#xff1a; 选择Open Git Bash here 接着gitclone&#xff0c;从gitee上面复制链接: https://gitee.com/hekai666/python-deeplearning.git 粘贴过来&#xff1a; 回车&#xff1a; 然后在本地就会多出来一个文件&#xff1a; 打开文件夹以…

C语言(13)------------>do-while循环

1.do-while循环的语法 我们知道C语言有三大结构&#xff0c;顺序、选择、循环。我们可以使用while循环、for循环、do-while循环实现循环结构。之前的博客中提及到了前两者的技术实现。可以参考&#xff1a; C语言&#xff08;11&#xff09;-------------&#xff1e;while循…

浏览器JS打不上断点,一点就跳到其他文件里。浏览器控制台 js打断点,指定的位置打不上断点,一打就跳到其他地方了。

关闭JavaScript 源代码映射&#xff0c;F12开发者模式 设置->偏好设置->源代码/来源->JavaScript 源代码映射。 肯定不是这个原因导致的&#xff0c;但这个办法可以暂时解决问题&#xff0c;点完这个东西就隐藏了webpack&#xff0c;有懂的来讲讲。 又浪费一个小时…

C++ 编程语言简介

C 是一种通用编程语言&#xff0c;它是作为 C 语言的增强而开发的&#xff0c;以包含面向对象的范例。它是一种命令式和编译语言。 C 是一种高级的通用编程语言&#xff0c;专为系统和应用程序编程而设计。它由贝尔实验室的 Bjarne Stroustrup 于 1983 年开发&#xff0c;作为…

山东大学软件学院nosql实验三

实验题目&#xff1a; 用Java做简单查询(2学时) 实验内容 用API方式&#xff0c;做简单查询。 实验要求 在以下要求中选择至少2个&#xff0c;使用Java语言实现数据查询&#xff0c;最终把数据输出到前端界面。 &#xff08;1&#xff09;找出年龄小于20岁的所有学生 &…

【NLP 38、激活函数 ④ GELU激活函数】

别盲目&#xff0c;别着急&#xff0c;慢慢走&#xff0c;没事的 —— 25.2.24 一、定义与数学表达式 GELU&#xff08;Gaussian Error Linear Unit&#xff0c;高斯误差线性单元&#xff09;是一种结合概率分布的非线性激活函数&#xff0c;其核心思想是通过输入值服从标准正…

突破性能极限:DeepSeek开源FlashMLA解码内核技术解析

引言&#xff1a;大模型时代的推理加速革命 在生成式AI大行其道的今天&#xff0c;如何提升大语言模型的推理效率已成为行业焦点。DeepSeek团队最新开源的FlashMLA项目凭借其惊人的性能表现引发关注——在H800 GPU上实现580 TFLOPS计算性能&#xff0c;这正是大模型推理优化的…

touchgfx的工作机制

touchgfx的工作机制 一.MVP软件架构 MVP的全称为Model-View-Presenter Model: 就是数据部分,在整个touchgfx应用中,只有一个Model类实例对象,它为所有的Screen屏幕界面服务,可以理解成是一个全局变量区,同时它还负责和后端系统通信 View: 就是UI界面部分,对应于View类,在整…

网站搭建wp

前置准备工作 需要下载Git&#xff0c;note.js&#xff0c;在官网上可以搜索并安装 搭建过程 这里借助hexo工具 1. 本地博客搭建 首先创建本地文件夹&#xff0c;并在该文件夹里面创建一个叫做hexo的文件夹在该文件夹中选择Git Bash 进入hexo官网将五条指令用bash运行运行…

现场可以通过手机或者pad实时拍照上传到大屏幕的照片墙现场大屏电子照片墙功能

现场可以通过手机或者pad实时拍照上传到大屏幕的照片墙现场大屏电子照片墙功能&#xff0c;每个人都可以通过手机实时拍照上传到大屏幕上,同时还可以发布留言内容&#xff0c;屏幕上会同步滚动播放展示所有人的照片和留言。相比校传统的照片直播功能更加灵活方便&#xff0c;而…

MySQL 主从复制原理及其工作过程

一、MySQL主从复制原理 MySQL 主从复制是一种将数据从一个 MySQL 数据库服务器&#xff08;主服务器&#xff0c;Master&#xff09;复制到一个或多个 MySQL 数据库服务器&#xff08;从服务器&#xff0c;Slave&#xff09;的技术。以下简述其原理&#xff0c;主要包含三个核…

【蓝桥杯单片机】第十三届省赛第二场

一、真题 二、模块构建 1.编写初始化函数(init.c) void Cls_Peripheral(void); 关闭led led对应的锁存器由Y4C控制关闭蜂鸣器和继电器 2.编写LED函数&#xff08;led.c&#xff09; void Led_Disp(unsigned char ucLed); 将ucLed取反的值赋给P0 开启锁存器 关闭锁存…

Android Coil3缩略图、默认占位图placeholder、error加载错误显示,Kotlin(3)

Android Coil3缩略图、默认占位图placeholder、error加载错误显示&#xff0c;Kotlin&#xff08;3&#xff09; Android Coil3缩略图、默认占位图placeholder、error加载错误显示&#xff0c;Kotlin&#xff08;1&#xff09;-CSDN博客文章浏览阅读667次&#xff0c;点赞18次&…

MariaDB 历史版本下载地址 —— 筑梦之路

MariaDB 官方yum源里面只有目前在维护的版本&#xff0c;而有时候对于老项目来说还是需要老版本的rpm包&#xff0c;国内很多镜像站都是同步的官方仓库&#xff0c;因此下载老版本也不好找&#xff0c;这里主要记录下从哪里可以下载到历史版本的MariaDB rpm包。 1. 官方归档网…