【Ⅵ树与二叉树】1.树的基本概念

一、树的定义

【1】引例

引例1树形思维导图
引例2电脑的文件结构
引例3树形结构

【2】定义

树由若干结点构成(N个),是一种非线性的数据结构(一对多)。

N = 0空树
N != 0唯一的根结点和若干个不相交的子树组成(每个子树也是一个树【递归定义】)

注意子树不能相交,有相交的子树整体就不是树形结构,结构就变成了图。

A是树的根节点,B、C、D是子树的根结点。

【3】说明

①树是一种逻辑结构,也是一种分层结构。

②树的根结点没有前驱结点。

③除根结点外的结点,有且只有一个前驱结点。

④树中所有结点可以有零个或多个后继结点。

⑤树适合于表示具有层次结构的数据。

⑥树中每个结点(除根结点),与上层一个结点有直接关系(边)。

⑦n个结点的树,有n-1条边。

二、基本术语

基本术语定义例子或说明
结点

结点内容由数据元素指向子树的分支组成

A、B、C……都是结点

结点A包含数据元素A和3个指向子树的指针

结点的度结点拥有的子树的个数(分支的个数)结点A的度为3
树的度树中各结点度的最大值上图中树的度为3(结点A、结点D)
叶子结点

度为0的结点,又叫作终端结点

F、G、I、J、K、L、M结点
非终端结点度不为0的结点,又叫作分支结点A、B、C、D、E、H结点
内部结点除了根结点外非叶子结点B、C、D、E、H结点
孩子某个结点的直接后继(可以有多个)结点A的孩子有B、C、D结点
双亲

某个结点的直接前驱(只有一个)

B、C、D结点的双亲都是A结点
兄弟拥有同一个双亲的结点之间互为兄弟B、C、D结点互为兄弟
祖先某结点开始到根结点的路径上的所有结点,叫作该结点的祖先K的祖先为E、B、A结点
子孙某结点为根的子树中的所有结点是该结点的子孙D的子孙为H、I、J、M结点
层次根为第一层,每向下一次增加一层上图中树的层次为4
路径两个结点的路径是由这两个结点之间所经过的结点序列构成的A、J结点之间的路径为(A、D)、(D、J)
路径长度路径上所经过的边的个数A、J结点之间的路径长度为2
树的路径长度从树根到每个结点的路径长度的总和具体学习与对比在哈夫曼树处
结点的高度

从该结点出发到达叶子结点,最长路径上的结点数为该结点在树中的高度

根结点的高度为树的高度

结点J的高度为1

结点的深度从根结点到该结点路径上的结点数结点J的深度为3
树的高度、深度结点的最大层次上图中树的高度(深度)为4
堂兄弟双亲在同一层的结点互为堂兄弟G、H结点互为堂兄弟
有序树树的左右子树不可交换的树交换后不是同一棵树
无序树树的左右子树可以交换的树交换后仍然是同一棵树
森林由若干棵互不相交的树组成的集合

★由于上面的术语记忆很杂乱,为大家准备了一张有趣的彩图,以助大家记忆理解★

三、树的性质

【1】树的总边数 = 树的所有结点的度数之和

原理:每个度都会对应一条边。

【2】树的结点数 = 树的所有结点的度数之和(树的总边数)+1

原理:1个结点有0条边、2个结点有1条边、···、n个结点有n-1条边。

【3】度为m的树,第i层上至多有m^{i-1}个结点(i>=1)

原理:当所有结点(除叶子结点)的度都是最大值m时,叶子结点只出现在最后一层时,树的每一层的结点数达到最多。第1层有1个结点、第2层有m个结点、第3层有m^{2}个结点、···、第i层有m^{i-1}个结点。

【4】高为h的m叉树至多有\frac{m^{h}-1}{m-1}个结点

原理:当所有结点(除叶子结点)的度都是最大值m时,叶子结点只出现在最后一层时,树的每一层的结点数达到最多。 第1层有1个结点、第2层有m个结点、第3层有m^{2}个结点、···、第h层有m^{h-1}个结点,等比数列求和,结果为\frac{m^{h}-1}{m-1}

【5】具有n个结点的m叉树的最小高度为\left \lceil \log _{m}\left [ n\left ( m-1 \right )+1 \right ] \right \rceil

原理:

四、树的存储结构

1、双亲表示法(顺序存储结构)

【1】前言

虽然后继的数量不确定,但是直接前驱只有一个呀!注意根没有直接前驱。

【2】实现

结构体 + 一维数组

结构体属性
data数据域,存储该结点的内容
parent指针域,存储该结点的双亲在数组中的下标(根节点的双亲下标为-1)

【3】存储结构描述

// 结构体
typedef struct
{
	ElemType data;
	int parent;
}PTNode;

// 一维数组
#define MAX_TREE_SIZE 100
typedef struct
{
	PTNode nodes[MAX_TREE_SIZE];  // 存储结点的数组
	int n;  // 真实结点数
}PTree;

【4】例子

【5】特点

①容易找到双亲结点,所用的时间复杂度为O(1)。

②找孩子要遍历整个结构才行,比如找A结点的孩子需要遍历整个数组,找到所有parent值为0的结点。

2、孩子表示法(链式存储结构)

方案一:孩子存储结构存储

【1】前言

双亲表示法存储的是双亲,向上查找;孩子存储结构存储的是孩子,向下查找.。

【2】结点内容

结点内容
data数据域
child指向所有孩子的指针域,按照树的度设计结点的孩子结点指针域个数

【3】例子

【4】特点

存储空间不能充分利用,会造成一些浪费(指针域)。

方案二:孩子链表表示法

【1】实现

孩子链表表示法是将每个结点的孩子结点都用单链表链接起来形成一个线性结构;n个结点就有n个孩子链表(叶子结点的孩子链表为空表)

【2】例子

【3】特点

①寻找孩子的操作非常直接。

②寻找双亲需要遍历n个孩子链表,比如找H结点的双亲,需要遍历所有孩子链表,找到H结点出现的那个链表,对应数组的值就是它的双亲。

③和孩子链表表示法相似的存储方式:图的邻接表表示法、稀疏矩阵的邻接表表示法。

3、孩子兄弟表示法(链式存储结构)

【1】结点内容

结点内容
data数据域
firstchild第一个孩子结点指针域
rightsib下一个兄弟结点指针域

【2】存储结构描述

typedef struct CSNode
{
	ElemType data;  // 数据域
	struct CSNode* firstchild,  // 指向第一个孩子的指针
		         * rightsib;  // 指向下一个兄弟的指针
}CSNode, * CStree;

【3】例子

【4】特点

①可以方便地实现树转二叉树。

②易于查找结点的孩子。

③查找双亲麻烦。.

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aspect of Twilight

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值