[数据结构](7)什么是树

什么是树?

树是一种非线性的数据结构,它是n(n >= 0)个有限元素的集合。

qXMnA0.jpg

  • 第一个结点称为根结点(root),根结点没有前驱结点。
  • 其余结点被分成M(M>0)个互不相交的集合T1、T2、……、Tm,其中每一个集合Ti(1<= i<= m)又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继。

注意:子树之间不能有交集

qx02h8.jpg

一些概念

qXMnA0.jpg

节点的度:一个节点含有的子树的个数称为该节点的度; 如上图:A的度为3
叶子节点或终端节点:度为0的节点称为叶节点; 如上图:J、F、K、L、H、I节点为叶节点
非终端节点或分支节点:度不为0的节点;
双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点; 如上图:A是B的父节点
孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点; 如上图:B是A的孩子节点
兄弟节点:具有相同父节点的节点互称为兄弟节点; 如上图:B、C是兄弟节点
树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为3
节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
树的高度或深度:树中节点的最大层次; 如上图:树的高度为4
堂兄弟节点:双亲在同一层的节点互为堂兄弟结点;如上图:F、G互为堂兄弟节点
节点的祖先:从根到该节点所经分支上的所有节点;如上图:A是所有节点的祖先;L的祖先是A、C、G、L(包括它自己)
子孙:以某节点为根的子树中任一节点都称为该节点的子孙。如上图:所有节点都是A的子孙
森林:由m(m>0)棵互不相交的树的集合称为森林;

树的表示

有些树的度可能比较大,比如一棵树的度为6,但不是每个结点的度都为6,难道每个结点都要存6个指针或者指针数组吗?

孩子兄弟表示法

一种优秀的表示方法。

结构如下,一个结点可以指向自己的第一个孩子或下一个兄弟。

父亲结点只要指向自己的第一个孩子,其它孩子依次连接在第一个孩子之后。

typedef int DataType;
struct Node
{
	struct Node* _firstChild1; // 第一个孩子结点
	struct Node* _pNextBrother; // 指向其下一个兄弟结点
	DataType _data; // 结点中的数据域
};

qzpQoQ.jpg


二叉树(重点)

二叉树就是度为2的树(各结点的度不大于2)

  • 二叉树可以为空
  • 由一个根结点和它的左子树和右子树组成
  • 左右子树有次序之分,不可颠倒。所以二叉树是有序树。

qzPYQI.jpgqziN9J.jpg

特殊的二叉树

满二叉树:如果一个二叉树每层的结点数都达到最大值,那么这个二叉树为满二叉树。如果满二叉树的层数为 k k k,则结点数为 2 k − 1 2^k-1 2k1

完全二叉树:完全二叉树是由满二叉树引申出来的,完全二叉树除了最底层可以不满,其余各层结点数都达到最大值。并且最底层结点都排在靠左侧的位置。满二叉树是特殊的完全二叉树。

qzcVyT.jpg

二叉树的性质

以下规定根结点的层数为1

  1. 一棵非空二叉树的第 i i i层上最多有 2 i − 1 2^{i-1} 2i1个结点
  2. 深度为 h h h的二叉树的最大结点数为 2 h − 1 2^h-1 2h1
  3. 结点数为 n n n的满二叉树的深度 h = log ⁡ 2 ( n + 1 ) h=\log_2(n+1) h=log2(n+1)
  4. 度为0的结点(叶结点)个数 n 0 n_0 n0比度为2结点个数 n 2 n_2 n2多一个,即 n 0 = n 2 + 1 n_0=n_2+1 n0=n2+1
  5. n n n个结点的完全二叉树按从上至下,从左至右的顺序存入数组。
    • 下标为 i ( i > 0 ) i(i>0) i(i>0)的结点,其父结点的下标为 ( i − 1 ) / 2 (i-1)/2 (i1)/2,下标 i = 0 i=0 i=0的是根结点,没有父结点。
    • 下标为 i i i的结点,其左孩子的下标为 2 ∗ i + 1 2*i+1 2i+1,右孩子的下标为 2 ∗ i + 2 2*i+2 2i+2,若计算结果大于 n − 1 n-1 n1则说明没有该孩子结点。

小练习:

  1. 某二叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该二叉树中的叶子结点数为( )
    A 不存在这样的二叉树
    B 200
    C 198
    D 199
  2. 下列数据结构中,不适合采用顺序存储结构的是( )
    A 非完全二叉树
    B 堆
    C 队列
    D 栈
  3. 在具有 2n 个结点的完全二叉树中,叶子结点个数为( )
    A n
    B n+1
    C n-1
    D n/2
  4. 一棵完全二叉树的节点数为531个,那么这棵树的高度为( )
    A 11
    B 10
    C 8
    D 12
  5. 一个具有767个节点的完全二叉树,其叶子节点个数为()
    A 383
    B 384
    C 385
    D 386

答案:BAABB

详解:

第3题:由题意 n 0 + n 1 + n 2 = 2 n n_0+n_1+n_2=2n n0+n1+n2=2n,又 n 0 = n 2 + 1 n_0=n_2+1 n0=n2+1,得 2 n 0 + n 1 − 1 = 2 n 2n_0+n_1-1=2n 2n0+n11=2n

完全二叉树度为 1 1 1的结点数只可能是 0 0 0 1 1 1,这里 n 1 n_1 n1只能为 1 1 1

解得 n 0 = n n_0=n n0=n,故选A

第4题 531 531 531 2 9 − 1 2^9-1 291 2 10 − 1 2^{10}-1 2101之间,所以高度为 10 10 10,故选B

第5题 767 767 767 2 9 − 1 2^9-1 291 2 10 − 1 2^{10}-1 2101之间,所以高度为 10 10 10,高度为9的满二叉树的结点数为 511 511 511,该二叉树最后一层结点数为 767 − 511 = 256 767-511=256 767511=256,倒数第二层结点数为 2 9 − 1 = 256 2^{9-1}=256 291=256,这一层的叶子结点数为 256 − 256 / 2 = 128 256-256/2=128 256256/2=128,总叶子结点数为 256 + 128 = 384 256+128=384 256+128=384,故选B

二叉树的存储结构

顺序存储

在性质5中已经讲到,二叉树是可以存进数组的,相当于给每个结点编号。我们也给出了父子结点下标之间的关系。

一般数组适合用来表示完全二叉树,否则会有空间的浪费。

这种存储结构虽然在物理上是一个数组,但逻辑结构还是二叉树

L9l9VU.jpg

非完全二叉树,某一层有可能没有塞满,那么存到数组中这个位置就必须空着,否则不满足性质5给的关系,也就不能表示相应的树的逻辑结构。

链式存储

链式存储就是最直观的,用链表的方式来存储。每个结点由三个域组成,左右指针域和数据域。

typedef int BTDataType;
struct BinaryTreeNode
{
    struct BinTreeNode* _pLeft; // 指向当前节点左孩子
	struct BinTreeNode* _pRight; // 指向当前节点右孩子
	BTDataType _data; // 当前节点值域
}

总结

本篇是对树的简单介绍,包括树的概念,表示。二叉树是其中的一个重要类型,我们浅谈了它的类型,性质,存储。

下一篇就要开始动手写代码了,主要是二叉树 堆的实现。

敬请期待。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

世真

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

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

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

打赏作者

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

抵扣说明:

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

余额充值