树的基本定义

news2025/1/14 18:19:13

树的基本术语

一个节点包括一下内容

  1. 父节点的地址值
  2. 左节点的地址值
  3. 右节点的地址值

如果没有父节点或者没有左右节点,那么这些节点对应的位置是 null
常见术语

  1. 节点—树中的元素常称为节点

  2. 边—根和它的子树根(如果存在)之间形成边的边可到达另一个结点,则称这两个结点间存在一条路径。

  3. 双亲—若一个结点有子树,那么该结点称为子树根的双亲

  4. 孩子—子树的根是该结点的孩子

  5. 兄弟—有相同双亲的结点互为兄弟

  6. 后裔—一个结点的所有子树上的任何结点都是该结点的后裔

  7. 祖先—从根结点到某个结点路径上的所有结点都是该结点的祖先

  8. 度—一个结点拥有的子树数量称为该结点的度。度为 0 的结点称为叶子结点,树中结点的最大的度称为树的度

  9. 层次—一般将根节点的层次定义为 1, 其余节点的层次等于其双亲结点的层次加 1, 书中节点的最大层次称为该树的高度

  10. 无序树, 有序树, 如果一棵树中各结点的子树的次序不重要,可以交换位置,这样的树称为无序树。如果将树中结点的各棵子树看成是从左到右有次序的,则称该树为有序树。从左到右,可分别称这些子树为第一子树、第二子树等。

  11. 森林—森林是树的有限集合

左子树

  • 对于任意一个节点 n,它的左子树是从根节点到 n 的路径上所有节点的集合,包括 n 自己。

右子树

  • 对于任意一个节点 n,它的右子树是从根节点到 n 的路径上所有节点的集合,不包括 n 自己。

二叉查找树
左节点的值比父亲节点的值小
右节点的值比父亲节点的值大
我们经常使用这个二叉查找树来进行查找节点

二叉树的遍历方式

三种递归遍历

  1. 我们定义了二叉树的四种遍历运算,即先序遍历、中序通历、后序遍历和层次遍历。其中先序遍历、中序遍历和后序遍历的设计思想与二叉树的递归定义密切相关

层次遍历

  1. 层次遍历是利用二叉树中各结点所在的层次,按照从上到下、从左到右的顺序访问二叉树中的每一个结点。

先序, 中序, 后序遍历

  1. 对于这三种遍历方法而言, 遍历的逻辑是没有什么区别的, 唯一的区别在于, 什么时候输出

  2. 函数的递归调用, 就是函数的自身调用, 执行完之后会返回上一个被嵌套的函数, 去执行, 未执行的表达式

  3. 假设 L、V 和 R 分别代表遍历左子树、访问根结点和遍历右子树这三个操作,那么就可以得到六种遍历次序,分别是 VLR、LVR、LRV、VRL、RVL 和 RLV。

  4. 即先访问根结点的先序遍历 VLR、中间访问根结点的中序遍历 LVR 和最后访问根结点的后序遍历 LRV

三种遍历算法的总结

  1. 先序遍历算法读取的时候输出是在第一个,也就是说每次执行函数都会有输出,其是先从根节点开始的,然后遍历左子树,和右子树,所以它的结果一般是,从根节点开始输出,然后不断输出根节点的左子树内容,然后是到最下面的左子树结点的时候,判断有没有左右子树,没有的话,判断上一个有没有右子树,有的话先输出右子树,然后在继续判断有没有左子树,,,,

  2. 中序遍历算法输出在遍历左子树之后,到最下面一个左子树才开始输出,然后是判断其有没有右子树,没有的话,返回上一步,此时上一步的遍历左子树算法结束,然后输出结点,然后继续遍历右子树,如果是先序遍历的话,此时这个右子树会输出的,但是中序遍历却不会输出,而是继续判断这个右子树有没有左子树之后才会输出。这就是区别

  3. 后序遍历,就是先到最下方的一个左子树,然后是返回上一个节点,此时先序和中序,都会输出上面的结点,但是后序不会,后序的话,是只有子树输出完了,才会输出双亲结点

前序遍历从跟节点开始左子节点,右子节点的顺序遍历
当前,左,右的遍历方式
中序遍历我们先遍历最左边的节点(即最左边的叶子节点),等这个节点遍历完之后我们就往上一层,如果有右节点,那么先观察它有没有左节点,如果有的话那么我们就遍历左节点
记住关键点,一切都是以左节点为先
后序遍历
左,右,当前节点
层次遍历
一层一层的遍历
java 中常见的二叉树类型其实和 C 语言是类似的,并不是通过其特有的 LinkHashSet 还是 LinkArraylist,亦或者是 LinkHashMap, 本质上还是通过类来进行构建的

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    
    public TreeNode(int val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}

public class BinaryTree {
    private TreeNode root;

    public BinaryTree() {
        this.root = null;
    }

    // 添加节点到二叉树
    public void addNode(int val) {
        root = addNodeRecursive(root, val);
    }

    // 递归方式添加节点到二叉树
    private TreeNode addNodeRecursive(TreeNode current, int val) {
        if (current == null) {
            return new TreeNode(val);
        }

        if (val < current.val) {
            current.left = addNodeRecursive(current.left, val);
        } else if (val > current.val) {
            current.right = addNodeRecursive(current.right, val);
        }

        return current;
    }

    // 遍历二叉树(示例为中序遍历)
    public void traverse() {
        traverseInOrder(root);
    }
    
    // 中序遍历二叉树
    private void traverseInOrder(TreeNode node) {
        if (node != null) {
            traverseInOrder(node.left);
            System.out.print(node.val + " ");
            traverseInOrder(node.right);
        }
    }

    public static void main(String[] args) {
        BinaryTree tree = new BinaryTree();

        // 添加节点
        tree.addNode(50);
        tree.addNode(30);
        tree.addNode(20);
        tree.addNode(40);
        tree.addNode(70);
        tree.addNode(60);
        tree.addNode(80);

        // 遍历二叉树
        tree.traverse();
    }
}

平衡二叉树

平衡二叉树的特点
二叉树左右两个子树的高度差不超过 1
任意节点的左右两个子树都是一颗平衡二叉树

平衡二叉树旋转
旋转触发时机
当添加一个节点之后, 该树不再是一颗平衡二叉树
左旋
就是将根节点的右侧往左拉, 原先的右子节点变成新的父节点, 并把多余的左子节点出让, 给已经降级的根节点当右子节点
从添加的节点开始,不断的往父节点中找不平衡的点
image.png
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
image.png

平衡右旋
右旋
就是将根节点的左侧往右拉, 左子节点变成了新的父节点, 并把多余的右子节点出让, 给已经降级根节点当左子节点
image.png

image.png

左右
左右: 当根节点左子树的右子树有节点插入, 导致二叉树不平衡
如何旋转: 先在左子树对应的节点位置进行左旋, 在对整体进行右旋
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们并不能通过一次旋转来实现这个二叉树的变换

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

红黑树

image.png

image.png

简单路径其实综合来说就是,不能回头
我们通过第五条规则来设定这个红色节点的数量

添加节点的规则

默认添加的节点是红色的,这样的话效率高

image.png

叔叔节点就是父节点的兄弟节点
根据这个操作来说,是不难的

红黑树是一种增删改查数据性能相对都较好的结构

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

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

相关文章

【数据结构】绪论

绪论 1.1数据结构的基本概念1.1.1 基本概念和术语1.1.2数据结构的三要素 1.2 算法与算法评价 1.1数据结构的基本概念 1.1.1 基本概念和术语 数据 数据是信息的载体&#xff0c;是描述客观事物属性的数、字符及所有能输入到计算机中并被计算机程序识别 和处理的符号的集合。数…

企业架构LNMP学习笔记17

反向代理&#xff1a; 反向代理服务器和真实访问的服务器是在一起的&#xff0c;有关联的。 根据实际业务需求&#xff0c;分发代理页面到不同的解释器。常见于代理后端服务器。 安装apache服务器&#xff1a; yum install -y httpd 修改配置文件&#xff1a; vim /et/http…

Postern配置HTTP和HTTPS的步骤

Postern是一款强大的Android代理工具&#xff0c;它允许您在设备上配置全局代理来实现安全、隐私保护和自由上网。本文将详细介绍如何使用Postern在Android设备上配置HTTP和HTTPS代理&#xff0c;为您提供更便捷的上网体验。 步骤1&#xff1a;下载和安装Postern应用 首先&am…

Threejs汽车展厅

2023-09-06-16-29-40 源码链接

浏览器安全-同源策略和CORS

同源策略 同源策略是浏览器的一个安全功能&#xff0c;浏览器禁止在当前域读写其他域的资源&#xff0c;如限制跨域发送ajax请求 不受同源策略限制的 1&#xff09;页面中的链接&#xff0c;重定向表单以及表单提交 2&#xff09;跨域资源引入 如script不受跨域限制&#xff0…

【网络编程】TCP传输控制协议(Transmission Control Protocol)

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…

pandas(四十三)Pandas实现复杂Excel的转置合并

一、Pandas实现复杂Excel的转置合并 读取并筛选第一张表 df1 pd.read_excel("第一个表.xlsx") df1# 删除无用列 df1 df1[[股票代码, 高数, 实际2]].copy() df1df1.dtypes股票代码 int64 高数 float64 实际2 int64 dtype: object读取并处理第二张表…

函数栈帧(详解)

一、前言&#xff1a; 环境&#xff1a;X86Vs2013 我们C语言学习过程中是否遇到过如下问题或者疑惑&#xff1a; 1、局部变量是如何创建的&#xff1f; 2、为什么局部变量的值是随机值&#xff1f; 3、函数是怎么传参的&#xff1f;传参的顺序是怎样的&#xff1f; 4、形…

Python实现猎人猎物优化算法(HPO)优化循环神经网络分类模型(LSTM分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 猎人猎物优化搜索算法(Hunter–prey optimizer, HPO)是由Naruei& Keynia于2022年提出的一种最新的…

【Arduino25】液晶模拟值实验

硬件准备 LCD1602显示屏&#xff1a;1 个 220欧的电阻&#xff1a;1 个 旋钮电位器&#xff1a;1 个 面包板&#xff1a;1个 杜邦线&#xff1a;若干 硬件连线 软件程序 #include <LiquidCrystal.h>LiquidCrystal lcd(12,11,5,4,3,2);void setup(){lcd.begin(16,2);…

UNIX网络编程卷一 学习笔记 第三十一章 流

在大多数源自SVR 4的内核中&#xff0c;X/Open传输接口&#xff08;X/Open Transport Interface&#xff0c;XTI&#xff0c;是独立于套接字API的另一个网络编程API&#xff09;和网络协议通常就像终端IO系统那样也使用流系统&#xff08;STREAMS system&#xff09;实现。 我…

VS Code断点调式Cesium

1.在VS Code中安装Debugger for Firefox插件 2.下载安Firefox Developer Edition 3. 创建launch.json 编辑并保存launch.json {// Use IntelliSense to learn about possible attributes.// Hover to view descriptions of existing attributes.// For more information, vis…

ETCD详解

一、etcd概念 ETCD 是一个高可用的分布式键值key-value数据库&#xff0c;可用于服务发现。 ETCD 采用raft 一致性算法&#xff0c;基于 Go语言实现。 etcd作为一个高可用键值存储系统&#xff0c;天生就是为集群化而设计的。由于Raft算法在做决策时需要多数节点的投票&…

06 科技英语|控制与优化学科词汇

maneuver n 策略&#xff1b;v 操控、调遣 manipulate vt 熟练控制 scalability n 可扩展性 leverage n 杠杆&#xff1b;v 促使...改变 flexibility n 弹性 dispatch n 急件&#xff1b;v 调度&#xff1b;派遣 leverage …

[TQLCTF 2022]simple_bypass

文章目录 涉及知识点解题过程 涉及知识点 无数字字母RCE自增马构造文件包含读取源码 解题过程 打开题目&#xff0c;随便注册一个用户为admin 登陆进去后&#xff0c;一眼发现杰哥图片有线索 我们F12看一下如何请求的 在这里发现可能存在文件包含漏洞 我们尝试读取下源码 …

深度优先搜索(dfs)--矩阵部分-leetcode以及常见题

介绍 深度优先搜索&#xff08;Depth-First Search&#xff0c;DFS&#xff09;是一种常用的图搜索算法&#xff0c;它用于查找图或树数据结构中的路径或解决问题。下面是深度优先搜索的常见步骤以及一个示例问题&#xff1a; 深度优先搜索的常见步骤&#xff1a; 选择起始节…

1分钟了解音频、语音数据和自然语言处理的关系

机器学习在日常场景中的应用 音频、语音数据和自然语言处理这三者正在不断促进人工智能技术的发展&#xff0c;人机交互也逐渐渗透进生活的每个角落。在各行各业包括零售业、银行、食品配送服务商&#xff09;的多样互动中&#xff0c;我们都能通过与某种形式的AI&#xff08;…

Flutter中系统Emoji通过substring裁切后无法识别导致渲染错误

Flutter中系统Emoji通过substring裁切无法识别、渲染错误 场景分析/思考寻找神马东西引起的渲染错误为什么 substring 之后就无法显示了 结论分析 substring 场景 在发布文章的时候&#xff0c;有标题和内容&#xff0c;标题可为空&#xff0c;在没有标题的情况下&#xff0c;…

大数据之MapReduce

MapReduce概述 是一个分布式的编程框架&#xff0c;MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序&#xff0c;并发运行在一个Hadoop集群上。 优点&#xff1a; 易于编程&#xff0c;简单的实现一些接口&#xff0c;就可以完成一…

CentOS 7删除virbr0虚拟网卡

在CentOS 7的安装过程中如果有选择相关虚拟化的的服务安装系统后&#xff0c;启动网卡时会发现有一个以网桥连接的私网地址的virbr0网卡&#xff0c;这个是因为在虚拟化中有使用到libvirtd服务生成的&#xff0c;如果不需要可以关闭后去掉&#xff1a; 一、查看IP及网桥设备 [r…