学二叉树之前,先来认识下树吧

简介: 学二叉树之前,先来认识下树吧

前言:

往期给大家讲了链表,栈,队列等数据结构, 它们都是线性结构,而今天要讲的是一种非线性结构:,让我们开始吧!


目录

🌳1.什么是树?

🪲2.有关树的概念

🎄3.树的表示

⛏️4.树的实际应用



1.什么是树?


树,木本植物之总名... ...欸,走错频道了?b5956884e42f6bf697d4a32f3f0b8410_2cd6a2ba941a46d59201828109093fb3.jpeg

其实数据结构中的树就是由大自然中的树定义来的,因为它们有很多相似之处:

c7fba5613f01894767c13e49279abe83_448094ba7b2f4d51af289a652b791eb9.png

              自然中的树(倒置)                               数据结构的树

怎么样?是不是还蛮像的🤩

自然地,最顶端的那个结点就叫做 根节点 (图中A结点)

此时引出树的概念:

树是一种非线性的数据结构,它是由 n (n>=0)个有限结点组成的一个具有层次关系的集合。

我们仔细来看看这颗树:

f70fdc3af2f594eddab1c7653b31a739_4a767d48b1b749f7bc0acff802bde6a2.png

从顶端开始,可以发现 根结点 以上是没有结点的,这里暂称为没有前驱结点

b52afee76df14ef76f4f430ce400a49f_0355411ddc904553a810d0a7d5a4eb5b.png

注意看,这棵树由根节点分出了三个方向,这三个箭头下又分别有一颗小树,我们称它们为子树。

子树2拿出来再进行分割:

50e75bdaba570dd4c956328ffd763e24_186898a8e5184990b4bde6ca04136603.png

子树2下又有子树2.1...

子树下有子树,子树下又有子树... ...

怎么有点像,

递归?

是的,可以理解为 树是递归定义的

接下来跟我看看下面的结构是不是树:

a0d92cbfcb95d552efe909f71b67ec1f_c2bf691f03dd46e9bd21cb9e9a805489.png

记住:这不是树,三条红边不能存在任意一条!!!

这部分的总结:

• 树顶端的结点称为根节点,根节点没有前驱结点;

• 子树之间不能相交🍌;

• 除了根节点之外,每个结点有且仅有一个前驱节点;

• 一棵N个结点的树有N-1条边;

• 树是递归定义的。


2.有关树的概念


为了更好介绍树的有关概念,这里画一个更复杂的树:

be11968ffaaaab12fb12372a1f3a3480_772c9654878d43e7ae937a78d541f9dd.png

结点的度:一个结点含有的子树个数(结点下的分支) 如结点A的度为5;

树的度:一棵树中最大的结点的度  如上树的度为5;

结点的层次:根是第1层,根的子节点所在层是第2层,如此递增;

树的高(深)度:最大的结点的层次  如上树的高(深)度是4;

叶子结点:度为0的结点(没有子树)  如结点 N,O;

双亲结点:如A是B,C,D,E,F的双亲结点;

(孩)子结点:如B,C,D,E,F是A的(孩)子结点;

兄弟结点:具有相同双亲结点的子节点  如G,H;

堂兄弟结点:双亲在同一层的结点互为堂兄弟结点  如H,I;

非终端结点/分支结点:度不为0的结点  如C,D,E...;

结点的祖先:从根节点所经分支上的所有结点  如A是所有结点的祖先;


3.树的表示


毕竟是代码人,知道了树的结构,就要考虑怎么表示树比较好,

先来想想具体需要表示什么:

一个是要存储的数据,

另一个是结点与结点之间的关系;

重点看后者:

要表示关系,最好是既能在一条线上深入,又能关系到临近的一条线。

我们想到了孩子与兄弟:

19b1741f30f52a3e36089273f2083951_0300ecd8e6d5498aa7679445d8e68e22.png

typedef int DataType;
struct Node
{
    struct Node* Child1; // 第一个孩子结点
    struct Node* brother; // 指向兄弟结点
    DataType data; // 结点中的数据域
};

除了孩子兄弟表示法这种最常见的表示法,此外还有双亲表示法,孩子表示法,孩子双亲表示法。

由于树的结构本身是具有不确定性的,所以这里不做深一步的实现,大家知道有这些表示方法就好。


4.树的实际应用


这里说个最典型的吧:

文件资源管理器中的文件管理就是一个树结构:

a71be874a293dc58073428551b6f18ef_bb9dc14d825047c2b8f118996a6348e7.png


总结:

这篇博客介绍了树,其实主要作用是为了后期二叉树做铺垫,大家了解它的结构,知道相关概念即可。

目录
相关文章
|
数据库
OVS 总体架构、源码结构及数据流程全面解析
在前文「从 Bridge 到 OVS」中,我们已经对 OVS 进行了一番探索。本文决定从 OVS 的整体架构到各个组件都进行一个详细的介绍。 OVS 架构 OVS 是产品级的虚拟交换机,大量应用在生产环境中,支撑整个数据中心虚拟网络的运转。
4673 0
|
7月前
|
存储 JavaScript 中间件
Vuex 中间件和 Pinia 中间件的性能有何区别?
Vuex 中间件和 Pinia 中间件的性能有何区别?
289 74
|
8月前
|
人工智能 中间件 程序员
大模型上下文协议 MCP 带来了哪些货币化机会
本文探讨了MCP(Model-Calling Protocol)的兴起及其对AI生态的影响。自2月中旬起,MCP热度显著提升,GitHub Star和搜索指数均呈现加速增长趋势。MCP通过标准化协议连接大模型与外部工具,解决了碎片化集成问题,推动AI应用货币化及生态繁荣。文章分析了MCP与Function Calling的区别,指出MCP更适用于跨平台、标准化场景,而Function Calling在特定实时任务中仍具优势。此外,MCP促进了 supply端(如云厂商、大模型、中间件服务商)和消费端(终端用户)的变革,尤其以Devin和Manus为代表,分别改变了程序员和普通用户的交互方式。
1011 37
大模型上下文协议 MCP 带来了哪些货币化机会
|
数据采集 前端开发 JavaScript
动态与静态网站抓取的区别:从抓取策略到性能优化
本文详细介绍了动态与静态网站抓取的区别、抓取策略及性能优化技巧,并提供了相关代码示例。静态网站抓取通过简单的HTTP请求和解析库实现,而动态网站则需使用Selenium等工具模拟浏览器执行JavaScript。文章还展示了如何使用代理IP、多线程和合理的请求头设置来提高抓取效率。
528 2
动态与静态网站抓取的区别:从抓取策略到性能优化
|
存储
指针和数组简单填空题合集(纯刷题:60道)
指针和数组简单填空题合集(纯刷题:60道)
264 0
|
算法 数据安全/隐私保护 异构计算
基于FPGA的BPSK调制解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本系统基于Vivado2019.2,在原有BPSK调制解调基础上新增高斯信道及误码率统计模块,可测试不同SNR条件下的误码性能。仿真结果显示,在SNR=0dB时误码较高,随着SNR增至5dB,误码率降低。理论上,BPSK与2ASK信号形式相似,但基带信号不同。BPSK信号功率谱仅含连续谱,且其频谱特性与2ASK相近。系统采用Verilog实现,包括调制、加噪、解调及误码统计等功能,通过改变`i_SNR`值可调整SNR进行测试。
364 1
|
机器学习/深度学习 安全 数据安全/隐私保护
Windows系统安装Jupyter Notebook并实现公网访问内网笔记服务
Windows系统安装Jupyter Notebook并实现公网访问内网笔记服务
428 0
|
存储 监控 Serverless
函数计算产品使用问题之T4和A10 GPU实例的区别有哪些
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
421 0
|
监控 安全 Java
Spring Boot优雅Shutdown时异步线程安全优化
Spring Boot优雅Shutdown时异步线程安全优化
|
移动开发 前端开发 JavaScript
uni-app使用WebSocket
uni-app使用WebSocket
1187 1