【数据结构】非线性表----树详解

是一种非线性结构,它是由**n(n>=0)**个有限结点组成一个具有层次关系的集合。具有层次关系则说明它的结构不再是线性表那样一对一,而是一对多的关系;随着层数的增加,每一层的元素个数也在不断变化(由上一层和该层的对应关系决定)。

关于树的名称的由来,是因为它的结构类型很像现实中的树倒过来,故称作——树。
在这里插入图片描述

根据树的名称,也对其所包含的元素进行了命名和定义。

树的基本术语

1.结点:包含一个数据元素及若干指向其子树的分支;

2.结点的度:一个结点拥有的子树的数目;

3.叶子或终端结点:度为0的结点;

4.非终端结点或分支结点:度不为0的结点;

5.树的度:树内各结点的度的最大值;(需要注意,树的度和结点的度的定义是有略微差异的)

除此之外,还使用人类亲缘关系进行了一系列描述:(注:下图的关系与节点名称无关,仅代表树的结构)
在这里插入图片描述

6.孩子结点或子结点:结点的子树的根称为该结点的孩子结点或子结点;

7.双亲结点或父结点:若一个结点含有子结点,则这个结点称为其子结点的双亲结点或父结点;

8.兄弟结点:同一个双亲的孩子之间互称兄弟;

9.祖先结点:从根到该结点所经分支上的所有结点;

10.子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙;

11.结点的层次:从根开始定义起,根为第一层,根的孩子为第二层。若某结点在第L层.则其子树的根就在第L+1层;

12.堂兄弟结点:其双亲在同一层的结点互为堂兄弟;

13.树的深度或高度:树中结点的最大层次;

14.森林:由m(m>=0)棵互不相交的树的集合称为森林;

15.有序树和无序树:树中结点的各子树从左到右是有次序的,不能互换,称该树为有序树,否则称为无序树;

16.路径和路径长度:路径是由树中的两个结点之间的结点序列构成的。而路径长度是路径上所经过的边的个数

树的基本特征

针对树,我们有很多可以说的点。这里我们主要从其结构特征来进行总结。

  • 任何一棵树都是由根和子树构成的——子树又是一棵树——树是递归定义的

  • 树的根结点没有前驱;除根结点外的所有结点有且只有一个前驱(也就是一个父节点)

  • 树中所有结点有零个或多个后继

  • 子树是不相交的。

  • 当不再有子树的时候就说明该树已经到了尾结点。

树的公式

事实上,基于树的数据结构,可以衍生出很多数学公式来对其进行计算,但是这里只介绍基本的两个(其他重要的公式会在二叉树中进行介绍)

节点数量
  • 对于一棵有 n 个节点的树,节点数量公式为:n = I + L 其中,I 是内节点数量,L 是叶节点数量。
边数
  • 一棵有 n 个节点的树有 n−1 条边。

树的构建

树的存储结构主要有以下几种方法,每种方法都有其优缺点和适用场景:

1. 父节点表示法(Parent Representation)

每个节点记录其父节点的编号或指针。这种方法使用一个数组,其中每个元素表示节点,其值是该节点的父节点的索引。

  • 结构

    parent[i] 表示第 i 个节点的父节点
    
  • 示例

    节点:  0  1  2  3  4  5
    父节点: -1  0  0  1  1  2  (-1 表示根节点)
    
  • 优点:简单,适合快速查找父节点。

  • 缺点:查找子节点较慢,需要遍历整个数组。

2. 孩子表示法(Child Representation)

每个节点记录其所有子节点。这种方法使用一个链表或数组,其中每个节点包含一个指向其子节点列表的指针。

  • 结构

    children[i] 表示第 i 个节点的子节点列表
    
  • 示例

    节点:   0  1  2  3  4  5
    子节点: [1,2] [3,4] [5] [] [] []
    
  • 优点:适合快速查找子节点。

  • 缺点:查找父节点较慢,需要记录父节点指针或进行额外处理。

以上两种方法的缺点和优点是互补的。那么是否有更为方便的方法呢?

3. 孩子兄弟表示法(Left-Child Right-Sibling Representation)

当我们需要定义很多孩子的时候,我们可以使用左孩子右兄弟的定义法

也就是说根节点只指向它的第一个孩子结点,而其他的孩子节点就交给第一个孩子节点去指向

将树转换为二叉树,每个节点记录其最左子节点和右兄弟节点。这种方法使用两个指针,一个指向最左子节点,另一个指向右兄弟。

  • 结构

    节点: node
    左孩子: leftChild
    右兄弟: rightSibling
    
  • 示例

    节点:    0/ \1   2/ \3   4
    转换为:
    节点:    0/  \1    2/3\4
    
  • 优点:能将任意树转换为二叉树,利用二叉树的遍历和处理方法。

  • 缺点:需要两个指针,内存开销较大。

4. 邻接表表示法(Adjacency List Representation)

通常用于存储图结构,但也可以用于树。每个节点记录其相邻节点(即子节点和父节点)。

  • 结构

    adjList[i] 表示第 i 个节点的相邻节点列表
    
  • 示例

    节点:   0  1  2  3  4  5
    相邻节点: [1,2] [0,3,4] [0,5] [1] [1] [2]
    
  • 优点:适合处理树和图的遍历和搜索。

  • 缺点:需要额外处理以区分子节点和父节点。

5. 邻接矩阵表示法(Adjacency Matrix Representation)

使用一个二维数组表示节点之间的连接关系。通常用于稠密图,但在某些情况下也可用于树。

  • 结构

    adjMatrix[i][j] 表示节点 i 和节点 j 之间是否有边(0 或 1)
    
  • 示例

    节点:  0  1  2  3  4  5
    邻接矩阵:
    [0, 1, 1, 0, 0, 0]
    [1, 0, 0, 1, 1, 0]
    [1, 0, 0, 0, 0, 1]
    [0, 1, 0, 0, 0, 0]
    [0, 1, 0, 0, 0, 0]
    [0, 0, 1, 0, 0, 0]
    
  • 优点:简单,适合快速查找任意两个节点之间是否有边。

  • 缺点:存储空间开销大,不适合稀疏树。

这些存储结构各有特点,选择哪种方法主要取决于具体应用需求,例如查找子节点还是父节点更频繁,内存开销是否是主要考虑因素等。

树的初始化和一些基本操作

#include <stdio.h>
#include <stdlib.h>// 定义树节点结构
typedef struct TreeNode {int data;struct TreeNode* child1;struct TreeNode* child2;struct TreeNode* child3;struct TreeNode* child4;...
} TreeNode;//树的初始化
TreeNode* createNode(int data)
{TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));if(!newNode){printf("failed!\n");return NULL;}newNode->data = data;newNode->child1 = NULL;newNode->child2 = NULL;...return newNode;
}//插入、查找、遍历...
TreeNode* insertTree(TreeNode* parent,int data);
TreeNode* findTree(TreeNode* parent,int data);
TreeNode* inorderTraversal(TreeNode* parent);
...

总结

单纯的树实际上用处不大(子节点过多)。但是对于文件系统、目录以及某些分层过多的系统,使用的就是树。

通常在优化的数据结构中,使用更多的是叫做二叉树的数据结构

这是基于树的数据结构,一个根节点只有两个孩子结点,在下一节我们将会对二叉树进行剖析,敬请期待。
在这里插入图片描述

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

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

相关文章

逆向案例二十三——请求头参数加密,某区块链交易逆向

网址&#xff1a;aHR0cHM6Ly93d3cub2tsaW5rLmNvbS96aC1oYW5zL2J0Yy90eC1saXN0L3BhZ2UvNAo 抓包分析&#xff0c;发现请求头有X-Apikey参数加密&#xff0c;其他表单和返回内容没有加密。 直接搜索关键字&#xff0c;X-Apikey&#xff0c;找到疑似加密位置&#xff0c;注意这里…

零基础学习Python(三)

1. 多重继承 一个子类可以继承多个父类&#xff0c;这与一些编程语言的规则不通。 如果多个父类中有同名的变量和方法&#xff0c;子类访问的顺序是按照继承时小括号里书写的顺序进行访问的。 可以用issubclass(B, A)方法判断B是否为A的子类。 2. 绑定 类中的方法通过参数s…

《TF2.x强化学习手册》P59-P65-SARSA-Q-learning

文章目录 实现SARSA算法和对应的强化学习智能体前期准备实现步骤工作原理初始化算法流程 构建基于Q学习的智能体前期准备实现步骤工作原理SARSA 算法的收敛性&#xff1a;SARSA 适合在线学习和真实系统&#xff1a;Q 学习算法的适用性&#xff1a; 实现SARSA算法和对应的强化学…

HDC使用常见命令

HDC&#xff08;HarmonyOS Device Connector&#xff09;是为开发人员提供的用于调试的命令行工具&#xff0c;通过该工具可以在windows/linux/mac系统上与真实设备进行交互。 使用HDC前&#xff0c;需要配置相关环境变量&#xff1a; 在此电脑 > 属性 > 高级系统设置 &g…

Git常用命令以及使用IDEA集成Gitee

目录 一、设置用户签名 二、初始化本地库 三、查看本地库状态 四、添加文件到暂存区 五、提交本地库 六、修改文件 七、版本穿梭 八、Git分支 九、分支的操作 9.1、查看分支 9.2、创建分支 9.3、切换分支 9.4、合并分支 十、团队协作 十一、Idea集成Git 11.1、配…

Github 2024-07-15 开源项目周报 Top15

根据Github Trendings的统计,本周(2024-07-15统计)共有15个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目5非开发语言项目4JavaScript项目3TypeScript项目2Go项目1Solidity项目1Java项目1Rust项目1免费编程学习平台:freeCodeCamp.org 创建…

3.1-RNN存在的问题以及LSTM的结构

文章目录 1 RNN存在的问题1.1梯度消失问题1.2梯度爆炸问题1.3梯度爆炸的对策 2梯度消失的对策——LSTM2.1输出门2.2遗忘门2.3输入门2.4总结2.5 LSTM梯度的流动 1 RNN存在的问题 RNN存在梯度消失和梯度爆炸的问题。 书上以下图的这句话为例&#xff0c;进行说明&#xff1b;为了…

前瞻断言与后瞻断言:JavaScript 正则表达式的秘密武器

JavaScript 中的前瞻断言&#xff08;lookahead&#xff09;和后瞻断言&#xff08;lookbehind&#xff09;相信用过的小伙伴就知道它的威力了&#xff0c;在一些特定的需求场景下&#xff0c;可以做到四两拨千斤的作用&#xff0c;今天让我们来盘点一下在 JavaScript 正则表达…

昇思25天学习打卡营第14天|munger85

基于MindNLPMusicGen生成自己的个性化音乐 这个所谓的个性化的音乐就是指你输入一段文字它会根据这个文字输出一段音乐这个音乐是贴近于那段文字的所以叫做文生成音乐&#xff0c; 如果网络正常的话就可以直接从下载这个模型。 那么音乐生成的有两种方式呢有两种方式&#xff…

【C++初阶】C/C++内存管理

【C初阶】C/C内存管理 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C&#x1f96d; &#x1f33c;文章目录&#x1f33c; 1. C/C内存分布 2. C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free 3. C内存管理方式 3…

拉格朗日乘子法和KKT条件

拉格朗日乘子法(Lagrange Multiplier) 和 KKT(Karush-Kuhn-Tucker) 条件是求解约束优化问题的重要方法&#xff0c;在有等式约束时使用拉格朗日乘子法&#xff0c;在有不等约束时使用 KKT 条件。当然&#xff0c;这两个方法求得的结果只是必要条件&#xff0c;只有当目标函数…

ssrf复习(及ctfshow351-360)

1. SSRF 概述 服务器会根据用户提交的URL发送一个HTTP请求。使用用户指定的URL&#xff0c;Web应用可以获取图片或者文件资源等。典型的例子是百度识图功能。 如果没有对用户提交URL和远端服务器所返回的信息做合适的验证或过滤&#xff0c;就有可能存在“请求伪造"的缺陷…

FPGA学习笔记(一) FPGA最小系统

文章目录 前言一、FPGA最小系统总结 前言 今天学习下FPGA的最小系统一、FPGA最小系统 FPGA最小系统与STM32最小系统类似&#xff0c;由供电电源&#xff0c;时钟电路晶振&#xff0c;复位和调试接口JTAG以及FLASH配置芯片组成&#xff0c;其与STM32最大的不同之处就是必须要有…

链表面试练习习题集(Java)

1. 思路&#xff1a; 因为杨辉三角是由二维数组构成&#xff0c;所以要先创建一个二维数组&#xff0c;如何用顺序表表示二维数组&#xff0c;可以通过List<List<Interger>>来表示一个二维数组&#xff0c;可以这样理解&#xff1a;先创建一个一维数组List&#x…

modbus slave 设备通过 网关thingsboard-gateway 将数据上传到thingsboard云平台

搭建thingsboard物联网云平台花了大量时间&#xff0c;从小白到最后搭建成功&#xff0c;折磨了好几天&#xff0c;也感谢网友的帮助&#xff0c;提供了思路最终成功搞定&#xff0c;特此记录。 一、thingsboard环境搭建&#xff08;Ubuntu20.04LTS&#xff09; 参考官方文档&a…

java之 junit单元测试案例【经典版】

一 junit单元测试 1.1 单元测试作用 单元测试要满足AIR原则&#xff0c;即 A&#xff1a; automatic 自动化&#xff1b; I: Independent 独立性&#xff1b; R&#xff1a;Repeatable 可重复&#xff1b; 2.单元测试必须使用assert来验证 1.2 案例1 常规单元测试 1.…

PSINS工具箱函数介绍——r2d

介绍工具箱里面r2d这个小函数的作用。 程序源码 function deg r2d(rad) % Convert angle unit from radian to degree % % Prototype: deg r2d(rad) % Input: rad - angle in radian(s) % Output: deg - angle in degree(s) % % See also r2dm, r2dms, d2r, dm2r, dms2r% …

多种方式实现 元素高度丝滑的从0-1显示出来

选择合适的方式&#xff0c;给用户更好的体验&#xff0c;多种方式实现 元素高度丝滑的从0-1显示出来。 能用 CSS 实现的动画&#xff0c;就不要采用 JS 去实现。 1、浏览器可以对CSS动画进行优化&#xff0c;其优化原理类似于requestAnimationFrame&#xff0c;会把每一帧的…

appium2.0 执行脚本遇到的问题

遇到的问题&#xff1a; appium 上的日志信息&#xff1a; 配置信息 方法一 之前用1.0的时候 地址默认加的 /wd/hub 在appium2.0上&#xff0c; 服务器默认路径是 / 如果要用/wd/hub 需要通过启动服务时设置基本路径 appium --base-path/wd/hub 这样就能正常执行了 方法二…

mysql的索引事务和存储引擎

一、索引 1、索引 索引的概念 &#xff1a;索引是一个排序的列表&#xff0c;在列表当中存储索引的值以及索引值对应数据所在的物理行。 索引的引用&#xff1a; 使用索引之后&#xff0c;就不需要扫描全表来定位某行的数据。 加快数据库的查询速度。 索引可以是表中的一…