树是一种非线性的数据结构,它是n(n >= 0)个有限元素的集合。
注意:子树之间不能有交集
节点的度:一个节点含有的子树的个数称为该节点的度; 如上图: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; // 结点中的数据域
};
二叉树就是度为2的树(各结点的度不大于2)
满二叉树:如果一个二叉树每层的结点数都达到最大值,那么这个二叉树为满二叉树。如果满二叉树的层数为 k k k,则结点数为 2 k − 1 2^k-1 2k−1
完全二叉树:完全二叉树是由满二叉树引申出来的,完全二叉树除了最底层可以不满,其余各层结点数都达到最大值。并且最底层结点都排在靠左侧的位置。满二叉树是特殊的完全二叉树。
以下规定根结点的层数为1
小练习:
- 某二叉树共有 399 个结点,其中有 199 个度为 2 的结点,则该二叉树中的叶子结点数为( )
A 不存在这样的二叉树
B 200
C 198
D 199- 下列数据结构中,不适合采用顺序存储结构的是( )
A 非完全二叉树
B 堆
C 队列
D 栈- 在具有 2n 个结点的完全二叉树中,叶子结点个数为( )
A n
B n+1
C n-1
D n/2- 一棵完全二叉树的节点数为531个,那么这棵树的高度为( )
A 11
B 10
C 8
D 12- 一个具有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+n1−1=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 29−1和 2 10 − 1 2^{10}-1 210−1之间,所以高度为 10 10 10,故选B
第5题: 767 767 767在 2 9 − 1 2^9-1 29−1和 2 10 − 1 2^{10}-1 210−1之间,所以高度为 10 10 10,高度为9的满二叉树的结点数为 511 511 511,该二叉树最后一层结点数为 767 − 511 = 256 767-511=256 767−511=256,倒数第二层结点数为 2 9 − 1 = 256 2^{9-1}=256 29−1=256,这一层的叶子结点数为 256 − 256 / 2 = 128 256-256/2=128 256−256/2=128,总叶子结点数为 256 + 128 = 384 256+128=384 256+128=384,故选B
在性质5中已经讲到,二叉树是可以存进数组的,相当于给每个结点编号。我们也给出了父子结点下标之间的关系。
一般数组适合用来表示完全二叉树,否则会有空间的浪费。
这种存储结构虽然在物理上是一个数组,但逻辑结构还是二叉树
非完全二叉树,某一层有可能没有塞满,那么存到数组中这个位置就必须空着,否则不满足性质5给的关系,也就不能表示相应的树的逻辑结构。
链式存储就是最直观的,用链表的方式来存储。每个结点由三个域组成,左右指针域和数据域。
typedef int BTDataType;
struct BinaryTreeNode
{
struct BinTreeNode* _pLeft; // 指向当前节点左孩子
struct BinTreeNode* _pRight; // 指向当前节点右孩子
BTDataType _data; // 当前节点值域
}
本篇是对树的简单介绍,包括树的概念,表示。二叉树是其中的一个重要类型,我们浅谈了它的类型,性质,存储。
下一篇就要开始动手写代码了,主要是二叉树 堆的实现。
敬请期待。