【Java】—— 二叉树

news2025/2/25 9:57:26

一、树型结构

        

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

  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;
    }

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

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

相关文章

机场导航系统有哪些功能?精准定位与高效路径规划技术深度剖析

本文专为关注机场服务优化、乘客体验提升的IT技术员及航空业同仁而写。将深入探讨机场室内导航系统的核心功能&#xff0c;旨在解决乘客在机场内部定位、路径规划、服务寻找等方面的痛点。如需获取机场导航系统解决方案可前往文章最下方获取&#xff0c;如有项目合作及技术交流…

医疗AI领域中GPU集群训练的关键技术与实践经验探究(上)

医疗AI领域中GPU集群训练的关键技术与实践经验探究(上) 一、引言 1.1 研究背景与意义 在科技飞速发展的当下,医疗 AI 作为人工智能技术与医疗领域深度融合的产物,正引领着医疗行业的深刻变革。近年来,医疗 AI 在疾病诊断、药物研发、健康管理等诸多方面取得了显著进展,…

STM32-智能小车项目

项目框图 ST-link接线 实物图&#xff1a; 正面&#xff1a; 反面&#xff1a; 相关内容 使用L9110S电机模块 电机驱动模块L9110S详解 | 良许嵌入式 一、让小车动起来 新建文件夹智能小车项目 在里面复制19-串口打印功能 重命名为01-让小车动起来 新建文件夹motor&…

星环科技推出DeepSeek全场景解决方案:即开即用、企业级部署、端侧智能三位一体

星环科技&#xff08;688031.SH&#xff09;正式发布DeepSeek全场景解决方案&#xff0c;全面覆盖个人用户、企业客户及行业场景需求&#xff0c;为用户提供从个人到企业、从云端到本地的全方位AI应用支持&#xff0c;为不同需求的用户提供了灵活、高效且安全的AI解决方案。 省…

《全星质量管理 QMS 软件系统》:赋能企业高效质量管理

《全星质量管理 QMS 软件系统》&#xff1a;赋能企业高效质量管理 在当今竞争激烈的商业环境中&#xff0c;《全星质量管理 QMS 软件系统》脱颖而出&#xff0c;展现出了显著且无可比拟的应用优势。 首先&#xff0c;《全星质量管理 QMS 软件系统》犹如一张严密的质量管控大网…

【多模态处理篇三】【DeepSeek语音合成:TTS音色克隆技术揭秘】

最近帮某明星工作室做AI语音助手时遇到魔幻需求——要求用5秒的咳嗽声克隆出完整音色!传统TTS系统直接翻车,生成的语音像得了重感冒的电音怪物。直到祭出DeepSeek的TTS音色克隆黑科技,才让AI语音从"机器朗读"进化到"声临其境"。今天我们就来扒开这个声音…

C++Qt学习笔记——实现一个串口通信界面

CQt学习笔记——实现一个串口通信界面 一.界面二、项目结构三、头文件1. 文件头部2. 类定义3. 构造函数和析构函数4. 成员函数5. 成员变量 四、代码解析ReceiveAeraInit 函数解析SerialHelper 构造函数解析1. 为什么有两个 SerialHelper&#xff1f;2. 为什么用 :: 和 :&#x…

Word(2010)排版技巧

设置标题样式 选择需要设置的标题 如下图所示。选择文字后&#xff0c;点击对应的样式即可设置。 设置标题格式 设置字体格式 设置段落格式 显示所有样式 标题样式展示 建议 建议新建一个正文样式&#xff0c;可以命名为正文1&#xff0c;因为所有的样式参考的“样式基准…

一.Vue中的条件渲染

1.在<head>中引用 <script src"https://unpkg.com/vue3/dist/vue.global.js"></script> 2.在<body>中写入 <div id"app"><p><a v-if "user.usernameadmin"href"#">编辑</a><a …

IO进程 day05

IO进程 day05 9. 进程9. 9. 守护进程守护进程的特点守护进程创建步骤 10. 线程10.1. 线程的概念10.2. 进程和线程的区别10.2. 线程资源10.3. 线程的函数接口1. pthread_create-创建线程线程函数和普通函数的区别 2. pthread_exit3.线程资源回收函数join和detach的区别 获取线程…

【HeadFirst系列之HeadFirstJava】第6天之认识Java的API:解锁高效开发的钥匙

认识Java的API&#xff1a;解锁高效开发的钥匙 在《Head First Java》的第六章节中&#xff0c;作者深入探讨了Java的API&#xff08;Application Programming Interface&#xff09;&#xff0c;并强调了它在Java开发中的重要性。Java API 是Java开发工具包&#xff08;JDK&a…

4 - AXI GPIO按键控制LED实验

文章目录 1 实验任务2 系统框图3 软件设计 1 实验任务 本实验任务是通过调用PL端AXI GPIO IP核&#xff0c;使用中断机制&#xff0c;实现PL端按键控制 PS端LED的功能。 2 系统框图 3 软件设计 注意事项&#xff1a; AXI GPIO IP核是双沿触发中断&#xff0c;不可设置&…

题海拾贝:扫雷

Hello大家好&#xff01;很高兴我们又见面啦&#xff01;给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 我的博客&#xff1a;<但凡. 我的专栏&#xff1a;《编程之路》、《数据结构与算法之美》、《题海拾贝》 欢迎点赞&#xff0c;关注&#xff01; 1、题…

Deepseek本地部署小实践(c盘)

目录 前言 一、安装ollama 二、打开终端执行run 三、可视化 前言 小鲸鱼出来以后看到很多大佬本地部署AI&#xff0c;自己也想试一试&#xff0c;第一次部署AI&#xff0c;选了一个简单的办法&#xff0c;实践一下&#xff0c;写得比较粗糙。 一、安装ollama 先简单的介绍…

详细解析d3dx9_27.dll丢失怎么办?如何快速修复d3dx9_27.dll

运行程序时提示“d3dx9_27.dll文件缺失”&#xff0c;通常由DirectX组件损坏或文件丢失引起。此问题可通过系统化修复方法解决&#xff0c;无需重装系统或软件。下文将详细说明具体步骤及注意事项。 一.d3dx9_27.dll缺失问题的本质解析 当系统提示“d3dx9_27.dll丢失”时&…

【LeetCode刷题之路】leetcode155.最小栈

LeetCode刷题记录 &#x1f310; 我的博客主页&#xff1a;iiiiiankor&#x1f3af; 如果你觉得我的内容对你有帮助&#xff0c;不妨点个赞&#x1f44d;、留个评论✍&#xff0c;或者收藏⭐&#xff0c;让我们一起进步&#xff01;&#x1f4dd; 专栏系列&#xff1a;LeetCode…

Vue全局变量的定义和使用,创建 Store变量、读取、修改

在VUE中&#xff0c;当需要各js、各页面都能读写的全局变量时&#xff0c;可以用store变量&#xff0c;从定义到使用的方法如下 一&#xff0e;定义变量&#xff0c;例&#xff1a;我们定一个全局变量gxh 找到 vue的/ src/ store路径, 在 modules文件夹下创建文件gvar.js 在…

基于Docker的前端环境管理:从开发环境到生产部署的实现方案

# 基于Docker的前端环境管理&#xff1a;从开发环境到生产部署的实现方案 简介及前端开发环境挑战 简介 是一种容器化平台&#xff0c;可以将应用程序及其依赖项打包为一个容器&#xff0c;提供一种轻量级、可移植的环境。它能够简化开发、部署和运维的流程&#xff0c;提高…

单片机延时函数怎么写规范?

我们以前在开发产品的时候&#xff0c;肯定会碰到一些延时需求&#xff0c;比如常见的LED闪烁&#xff0c;按键消抖&#xff0c;控制IO口输出时序等等。 别小看延时&#xff0c;这个小问题&#xff0c;想做好&#xff0c;甚至要考虑到程序架构层面。 在开发板上&#xff0c;可能…

数据结构 1-2 线性表的链式存储-链表

1 原理 顺序表的缺点&#xff1a; 插入和删除移动大量元素数组的大小不好控制占用一大段连续的存储空间&#xff0c;造成很多碎片 链表规避了上述顺序表缺点 逻辑上相邻的两个元素在物理位置上不相邻 头结点 L&#xff1a;头指针 头指针&#xff1a;链表中第一个结点的存储…