一起学数据结构(7)——树及二叉树的基本概念及存储

news2024/9/30 1:42:39

前面的关于数据结构的文章中,介绍了顺序表,链表,栈,队列等数据结构。对于以上数据结构,均是一对一的关系。本篇文章将对于一对多的数据结构——树进行解析。

目录

1. 树的定义及基本概念:

1.1 树的定义:

1.2 树的基本概念及术语:

2. 树的存储:

3. 二叉树的概念及结构 :

3.1 二叉树的概念:

3.2 两种特殊的二叉树:

3.2.1 满二叉树:

3.2.2 完全二叉树:

3.3 二叉树的存储:

3.3.1 完全二叉树的存储:

3.3.2堆的相关概念:

3.3.3 非完全二叉树的存储:


1. 树的定义及基本概念:

1.1 树的定义:

树是n(n\geq 0)个结点的有限集,当n =0时,把树称之为空树。对于任意的非空树,应该满足下面的条件:

1. 有且仅有一个特定的结点

2.当n> 1时,除根结点之外的其他结点可以再分为m(m> 0)个互不相交的有限集T_{1},T_{2},T_{3}......T_{n},并且每个有限集本身也可以看作一棵树,并且称之为根的子树。

树的结构可以由下图表示:


从给出的树的结构图可以看出,树的定义是满足递归的,即:树在定义的过程中,多次用到了自身。所以,树是一种递归的数据结构,同时,满足下面的两个特点:

(1).根结点没有前驱,除根结点以外的结点有且仅有一个前驱。如果对上述树的结构图进行更改:

本图中L结点因为由两个前驱,即E,F结点。所以,上图不满足树的结构,不为树。

(2).树中所有结点都可以又零个或者多个后继结点。 

1.2 树的基本概念及术语:

(1).结点的度:一个结点含有子树的个数,被称之为该结点的度,图中,A结点的度为3

(2).叶结点或终端结点:度为0的结点称之为叶结点,图中G,I,J均为叶结点。

(3).非终端结点或分支结点:度不为0的结点为分支结点。图中B,C,D,E均为分支结点。

(4).双亲结点或者父结点:若一个结点含有一个子结点,则这个结点称为子结点的父结点。

(5).子结点:一个结点含有的子树的根结点,称之为该结点的子结点,图中B,C,D均为结点A的子结点。

(6).兄弟结点:具有相同父结点的结点,称之为兄弟结点。

(7).树的度:树中最大的结点的度,称之为树的度。图中树的度为3.

(8).结点的层次:从根结点开始定义,根结点为第1层,以此类推。

(9).树的高度:树中最大的结点的层次,图中树的高度为4

(10).堂兄弟结点:父结点在同一层的结点,称之为堂兄弟结点,图中F,G,就互为堂兄弟结点。

(11).结点的祖先:从根到该结点所经分支的所有结点。例如,图中的祖先结点为A

(12).子孙结点:以某结点为根的子树中任一结点都为该结点的子孙结点。

(13).森林:m(m>0)棵互不相交的树构成的集合称之为森林。

2. 树的存储:

在存储上述给出的树时,由于每一个结点下面的子结点的数量都是随机的,所以,只有在得知结点的度的情况下,才可以提前开辟一定量的空间进行存储。但是在大多数情况下,结点的度都是未知的,对于上述情况,采取的存储方式为左孩子,右兄弟的存储方法,具体结构如下:

struct TreeNode
{
     int val;
     struct TreeNode* firstchild;
     struct TreeNode* nextbrother;
};

其中,val用于存储数据元素,结构体指针firstchild用于指向该结点最靠左部分的子结点,nextbrother用于指向子结点的兄弟结点。

若用上面的存储方法来表示给出的树的结构,其中红线表示结构体指针firstchild的指向,蓝线表示结构体指针nextbrother的指向,效果图如下:

对于由m(m>0)棵互不相交的树构成的森林,也可以采用双亲表示法进行存储,原理如下:

在采用双亲表示法对上述的森林进行存储时,需要创建一定大小的数组,用于存放若干个结构体,每个结构体均是森林中子树的结点,即:

在上一个存储方法中,分别存储了子结点和兄弟结点的地址。对于双亲表示法,则是存储该结点父结点的指针或者下标。 例如上面给出的数组,若该结点不存在父结点,则直接存储-1,若存在父结点,需要存储父结点的下标,效果如下:

其中,绿色数字代表该结点的父结点的下标。

从上面对于树的简单介绍可以看出,相对于之前的顺序表,链表等数据结构来说,树的结构较为复杂。但是,在实际使用时,只有二叉树这一种特殊的结构比较泛用,下面将对于二叉树的内容进行介绍。

3. 二叉树的概念及结构 :

3.1 二叉树的概念:

二叉树是一种特殊的数据结构,特点是每个结点至多只有两棵子树,即:二叉树中不存在度大于2的结点。并且二叉树有左右之分,且顺序不可以颠倒。

与树相同,二叉树也是由n(n\geq 0)个结点构成的有限集合。当n=1时,此时的二叉树被称之为空树。n = 1时,此时二叉树只有一个根节点。当n = 2时,此时的二叉树有左树、右树两种形式。当n=3是,此时的二叉树有左、右两棵子树。即:

n > 3的任意二叉树,均可以看作由上述情况复合而来。

3.2 两种特殊的二叉树:

3.2.1 满二叉树:

对于一个二叉树,如果每一层的结点数都到达了最大值,则称这个二叉树为满二叉树,满二叉树结构如下:


对于一个高度为n的满二叉树,由于每一层的结点都达到了最大值,满二叉树中的结点总数为2^n-1

3.2.2 完全二叉树:

对于完全二叉树,是一种效率很高的数据结构,完全二叉树是由满二叉树引出来的。对于一个高度为n,有m个结点的二叉树,当且仅当每一个结点都与高度为n的满二叉树编号从1n的结点一一对应时,称之为完全二叉树。对于满二叉树,可以看作成一种特殊的完全二叉树。也可以理解为,一个高度为m的完全二叉树,其前m-1层的结点数都达到了最大值。但是在第m层,结点的数量可以小于最大值,但是结点的排列必须是连续的,即下图中所展示的结构。:

而对于下面这种结点排列不连续的二叉树,则不可以看作完全二叉树:

前面说到,满二叉树可以看作一个特殊的完全二叉树。故,一个完全二叉树的结点数量的最大值为2^n-1。通过上述给出的完全二叉树的结构,可以的出,当完全二叉树结点数量的最小值,就是第m层只有一个结点,结构如下:

此时的完全二叉树的结点数量为2^{n-1}.所以,完全二叉树的结点数量的范围k为:                  

                                                           2^{n-1}\leq k\leq 2^{n}-1 

3.3 二叉树的存储:

3.3.1 完全二叉树的存储:

对于一个完全二叉树,在进行存储时,可以采用顺序存储的方式进行存储,例如对于下列完全二叉树:

其顺序存储方式可以表示为:

通过数组的下标,可以总结出下面的等式:

对于每个父结点,其左子结点的下标为child = parent*2+1。其右子结点的下标为:child = parent*2+2。对于每个子结点,其父结点的下标可以表示为:parent = (child-1)/2,左、右子结点均通用。

3.3.2堆的相关概念:

对于完全二叉树的顺序存储,一个比较典型的例子就是堆:堆是一个非线性结构的数据结构,结构上满足完全二叉树,适合用顺序存储。堆可以分为两种:

(1).小堆:树中任何一个父节点存储的值都\leq子结点存储的值。

顺序存储可以表示为:

(2).大堆:树中任何一个父结点存储的值都\geq子结点存储的值。例如:

3.3.3 非完全二叉树的存储:

将上面给出的完全二叉树删除其中的几个结点,改造成非完全二叉树。如果用顺序存储方式来存储非完全二叉树,则其顺序存储方式可以表示为:

 

对应非完全二叉树的结构为:

对于给出的非二叉树,将不再适用于上面给出的两个等式。这是因为,当在计算机中建立上述非完全二叉树时,二叉树的结构与图中表示不同,而是把F看作B的一个子结点,而非C的子结点。也就是说,F的下标应该是4E的坐标为3,与顺序表示方法中的下标编号不同。故不能采用顺序存储。

对于非完全二叉树的存储,一般采用链式存储。


 

                             

                                                             

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

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

相关文章

结合el-tooltip,实现内容过长省略,移上显示全部

在系统中,内容过长需要省略,鼠标移上显示全部,这个是常用的功能,也有很多方案解决这种。 单行内容超出处理 常用的css方案: .ellipsis {overflow: hidden;white-space: nowrap;text-overflow: ellipsis; } 该样式在…

基于Android系统英语学习助手APP设计开发

一、 设计思路 1.1设计目标 1.2设计思路 1.3设计内容 1.3.1界面设计 1.3.2功能模块设计 1.3.3功能流程图 1.3.4数据库设计(如果没有数据库这部分删除) 1.4工具设备要求 1.5技术方案 二、设计过程与说明 2.1技术路线 2.2实现方案 2.3实现原理…

C#复习:面向对象基本概念

C#复习:面向对象基本概念 前言什么是面向对象类,名称空间的介绍 如何导入类库DLL引用(黑盒引用)项目引用(白盒引用)NuGet介绍 依赖关系C#的分装(个人理解) 前言 关于我C#的博客是根据刘铁猛老师的C#入门课程为基础写的,可以配合刘铁猛老师的…

.bat批处理命令处理文件

批处理命令处理文件找到上级目录,并删除文件与文件夹 参考资料: [BAT] 如何获取bat的上一级目录、上两级目录..._bat 上层目录_Risun_Lee的博客-CSDN博客echo offset currPath%~dp0set parentPathset parentparentPath:beginfor /f "tokens1,* de…

solidworks导出文本能打开的stl文件

几种以文本格式(ASCII)导出stl的设置 1.solidworks导出时需要在选项里设置导出格式为ASCII,当选择以二进制格式导出时,打开会乱码; 2.CAD直接导出的是以二进制形式导出的,导出后也无法使用文本打开&#xf…

NVIDIA DALI学习:数据加载

DALI的工作流, 如下图: 读取数据图像解码和变换,可以放到GPU上进行,也是加速的关键生成处理好的数据, 导出给计算引擎 测试用例 import ctypesimport numpy as np import nvidia.dali.fn as fn import nvidia.dali…

关于Godot动态生成节点的细节

var dy_btn Button.new()add_child(dy_btn)print(get_child(0).name) 此时获取的名词会带有动态类型,如果这个时候想通过特定的节点名词来获取节点是不行的 此时需要补充类似 dy_btn.name "a" 的代码,然后就能按照节点名词获取节点了

Java下打印九九乘法表

这个算法是基于打直角三角型演变而来&#xff0c;代码如下&#xff1a; public class MyWork {public static void main(String[] args) {for (int i 1; i < 10; i) {for (int j 1; j < i; j) {System.out.print(j "x" i "" i*j "\t&qu…

使用Arduino简单测试HC-08蓝牙模块

目录 模块简介模块测试接线代码测试现象 总结 模块简介 HC-08 蓝牙串口通信模块是新一代的基于 Bluetooth Specification V4.0 BLE 蓝牙协议的数传模块。无线工作频段为 2.4GHz ISM&#xff0c;调制方式是 GFSK。模块最大发射功率为4dBm&#xff0c;接收灵度-93dBm&#xff0c…

软考软件设计师-计算机组成与体系结构(上

软考中级 一、数据的表示如果是其他进制 二、把十进制转其他进制【短除法三、存储系统的层次结构存储系统-存储器的分类 四、把二进制转8进制与16进制二进制转8进制二进制转16进制 五、原码、反码、补码原码反码补码移码原码 反码 补码的取值范围 六、数据的表示-浮点数运算七、…

TienChin 渠道管理-配置字典常量

在字典管理当中添加渠道状态 channel_status&#xff1a;渠道状态 分别为&#xff1a; 正常&#xff0c;键值为1&#xff0c;回显样式为 success 禁用&#xff0c;键值为0&#xff0c;回显样式为 info !> 有个注意点&#xff1a;Vue3 当中 v-for 与 v-if 不能写在一起。 在上…

Linux 查看进程和线程

ps命令 在ps命令中&#xff0c;“-T”选项可以开启线程查看。下面的命令列出了由进程号为<pid>的进程创建的所有线程。 ps -T -p <pid> “SID”栏表示线程ID&#xff0c;而“CMD”栏则显示了线程名称。 你可以用 ps -eLf |grep XXX 来查看程序运行所产生的线程情…

005:vue2使用vue-type-writer实现打字机效果

Vue Type Writer是一个Vue.js 2打字机效果组件&#xff0c;支持像打字机一样模仿键入文本。 文章目录 1. 效果2. 安装使用 1. 效果 2. 安装使用 npm 安装 npm install vue-type-writer --save完整代码 <template><div class"app-container home"><…

MyBatis 高级使用

文章目录 动态SQL语句ifchoosetrimforeach 批量操作批量插入批量更新批量删除BatchExecutor 关联查询嵌套查询延迟加载 分页操作逻辑分页物理分页 MyBatis Generator添加配置文件添加插件生成 通用Mapper方式一方式二 MyBatis-Plus 动态SQL语句 动态 SQL 是 MyBatis 的强大特性…

【运维篇】二、配置文件与多环境控制

文章目录 1、临时属性2、IDEA中的临时属性3、配置文件4级分类4、关于四级分类的思考5、自定义配置文件6、多环境开发&#xff08;yaml版&#xff09;7、配置文件按环境分类8、include与group再细粒度9、一点思考10、多环境开发兼容问题 1、临时属性 jar包或者镜像已经打完了&a…

根据每帧点云的PCD文件和每帧的位姿合成整个点云地图(附python open3d 代码)

现在有多个PCD文件表示每帧的点云,有一个位姿文件,里面是每帧的位姿,需要根据每帧点云和每帧的位姿合成整个地图。 首先,从文件中读取所有点云文件的路径,并将其存储到一个列表中。然后,读取位姿文件,并将其转换为一个 3x4 的矩阵。 然后,遍历所有点云文件。对于每帧点…

如何通过简历展示自己的执行力和动力?

导语: 简历是求职过程中的重要工具&#xff0c;通过合适的展示方式能够有效地展示自己的执行力和动力。本文将分享一些技巧&#xff0c;帮助您在简历中突出这两个关键能力。 突出成就和项目经历: 在简历中详细描述您曾经完成的项目或工作&#xff0c;并着重强调其中的具体成果…

ICS TRIPLEX T9402 自动化控制模块

ICS TRIPLEX T9402 是一款自动化控制模块&#xff0c;通常用于工业自动化和控制系统中&#xff0c;用于监测、控制和自动化各种工业过程。以下是该产品的一些主要特点&#xff1a; 可靠性&#xff1a; T9402 模块通常具有高可靠性&#xff0c;以确保系统能够稳定运行&#xff0…

开学季哪个牌子的电容笔好?ipad2023手写笔推荐

到底是用苹果原装的电容笔&#xff0c;还是用平替的电容笔&#xff0c;这要根据自己的需要来决定&#xff0c;比如经常用在画画上&#xff0c;可以选择苹果原装笔&#xff1b;如果你一天里用来写东西的时间多于用来画画的时间&#xff0c;那你就该考虑一下&#xff0c;买一支更…