树与二叉树
一、概念
1. 数据结构
一般情况下,我们会将数据结构分为逻辑结构和物理结构,其中逻辑结构是我们的逻辑下存储的结构,而物理结构是计算机的逻辑下存储的结构。数据结构的分类可以参见下表:
2. 树的基础知识
树是一种非线性的数据结构,由节点和边组成。树是有 n n n( n ≥ 0 n \ge 0 n≥0)个结点组成的具有分支和层次特性的数据集合。
树当中的数据就是 结点。
结点的深度:设根节点的深度为
1
1
1(根据题目),其他根节点深度为其父节点深度加
1
1
1。
结点的高度:设叶节点的高度为
1
1
1(根据题目),其他结点高度为其他子结点高度加
1
1
1。
层次:从跟开始,根为第
1
1
1 层,根的子节点为第
2
2
2 层,以此类推。
路径:对于树中两点不同的结点,如果从一个结点出发,自上而下沿着树中连着结点的线段能到达另一个结点,称为它们之间存在着一条路径。
遍历:分为四种遍历:
- 先序(根)遍历
先遍历根结点,然后遍历左子树和右子树 - 中序(根)遍历
先遍历左子树,再遍历根节点和右子树 - 后序(根)遍历
先遍历左子树,在遍历右子树和根结点 - 层序(根)遍历
一层一层地遍历
一棵树中,结点最大的度就是 树的度。
一个结点拥有子树的个数称为 结点的度。
具有相同父结点的结点被称为 兄弟结点。
某个结点的直接后继结点被称为该结点的 子结点。
某个结点的直接前驱结点被称为该结点的 父结点。
没有直接前驱,只有直接后继的结点为 根结点。
一棵树中,度为
0
0
0 的结点称为 叶结点。
当
n
>
1
n>1
n>1 的时候,除根结点以外其余结点可以分为m个互不相交的有限集合,其中每个集合本身又是一棵树,这些集合称为这棵树的 子树。
当有
m
m
m(
m
≥
1
m\ge1
m≥1)个树的集合时,称呼其为 森林。
当
n
=
0
n=0
n=0 的时候,树为 空树。
如果你看着觉得很花,可以看一看下图:
3. 树的相关概念
性质1: 树中的结点数等于所有结点的度之和加
1
1
1,即:
n
=
1
+
n
1
×
1
+
n
2
×
2
+
⋯
n=1+n_1\times1+n_2\times2+\cdots
n=1+n1×1+n2×2+⋯
性质2: 树中的结点树等于所有结点个数总和,即:
n
=
n
0
+
n
1
+
n
2
+
⋯
n=n_0+n_1+n_2+\cdots
n=n0+n1+n2+⋯
性质3: n n n 个结点的树中有 n − 1 n-1 n−1 条边。
4. 二叉树的特点
二叉树(binary tree, BT \text{BT} BT)是一种特殊的树型结构,二叉树的每个结点最多有两个子结点(即二叉树中不存在度大于 2 2 2 的结点)。每个结点的子结点分别称为左孩子、右孩子,它的两颗子树分别称为左子树、右子树。
二叉树的基本形态:
- 左右子树都有
- 只有左子树
- 只有右子树
- 只有根结点
- 空树
5. 二叉树的概念
性质1: 在二叉树中,可以根据树的
1
,
2
1,2
1,2 两个性质进行简化:
n
0
=
n
2
+
1
n_0=n_2+1
n0=n2+1
性质2: 在二叉树中,第 k k k 层最多有 2 k − 1 2^{k-1} 2k−1 个结点( k ≥ 1 k\ge1 k≥1)。
性质3: 二叉树的高度为 h h h,则整个二叉树最多有 2 h − 1 2^{h}-1 2h−1 个结点( h ≥ 1 h\ge1 h≥1)。
6. 特殊二叉树
6.1 满二叉树
满二叉树:高度为 h h h 且含有 2 h − 1 2^h-1 2h−1 个结点的二叉树(即每个结点都分出两个叉的树)。
满二叉树的编号:编号为 i i i 的结点,父节点编号为 ⌊ 1 2 i ⌋ \lfloor \frac{1}{2}i \rfloor ⌊21i⌋,左孩子为 2 i 2i 2i,右孩子为 2 i + 1 2i+1 2i+1。
6.2 完全二叉树
完全二叉树:在满二叉树的基础上,省略了最后面的一部分编号。
完全二叉树的特点:若有度为 1 1 1 的结点,则只可能有 1 1 1 个,且该结点只有左孩子而无右孩子。
完全二叉树的性质:
(1)按照层次编号后,一旦出现某个编号为
i
i
i 的结点为叶节点或只有左孩子,则编号大于
i
i
i 的结点均为叶节点。
(2)若 n n n 为偶数,则编号为 n ÷ 2 n\div2 n÷2 的结点只有左孩子,没有右孩子,叶结点数量为 n ÷ 2 n\div2 n÷2;反之,若 n n n 为奇数,则没有度为 1 1 1 的结点,叶节点数量等于 ⌈ n ÷ 2 ⌉ \lceil n\div2 \rceil ⌈n÷2⌉。
二、例题
1. 树
-
设在一颗度为 2 2 2 的树中,度数为 2 2 2 的结点有 3 3 3 个,度数为 1 1 1 的结点有 2 2 2 个,那么度数为 0 0 0 的结点有(_____)个。
【答案】 4 4 4
【解析】 在一颗树种,结点最大的度是 2 2 2。根据树的性质 1 1 1, n = 1 + n 1 × 1 + n 2 × 2 = 1 + 2 × 1 + 2 × 3 = 9 n=1+n_1\times1+n_2\times2=1+2\times1+2\times3=9 n=1+n1×1+n2×2=1+2×1+2×3=9。然后根据树的性质 2 2 2, n = n 0 + n 1 + n 2 n=n_0+n_1+n_2 n=n0+n1+n2, n 0 = 9 − ( 3 + 2 ) = 4 n_0=9-(3+2)=4 n0=9−(3+2)=4。故填 4 4 4。 -
设在一颗度为 4 4 4 的树中,度数为 4 4 4 的结点有 1 1 1 个,度数为 3 3 3 的结点有 1 1 1 个,度数为 2 2 2 的结点有 2 2 2 个,度数为 1 1 1 的结点有 4 4 4 个,那么度数为 0 0 0 的结点有(_____)个。
【答案】 8 8 8
【解析】 在一颗树种,结点最大的度是 2 2 2。根据树的性质 1 1 1, n = 1 + 4 × 1 + 2 × 2 + 1 × 3 + 1 × 4 = 1 + 4 + 4 + 3 + 4 = 16 n=1+4\times1+2\times2+1\times3+1\times4=1+4+4+3+4=16 n=1+4×1+2×2+1×3+1×4=1+4+4+3+4=16。然后根据树的性质 2 2 2, n 0 = 16 − ( 4 + 2 + 1 + 1 ) = 8 n_0=16-(4+2+1+1)=8 n0=16−(4+2+1+1)=8。故填 8 8 8。
2. 二叉树
-
【NOIP 2010 普及组 T5】 如果树根算第一层,那么一颗 n n n 层的二叉树最多有(_____)个结点。
【答案】 2 n − 1 2^n-1 2n−1
【解析】 直接套公式。 -
【NOIP 2009 普及组 T14】 一个包含 n n n 个分支结点(非叶节点)的非空二叉树,这棵树的叶节点数目最多为(_____)。
【答案】 n + 1 n+1 n+1
【解析】 根据二叉树的第一个性质和题目描述, n 1 + n 2 = n n_1+n_2=n n1+n2=n, n 0 = n 2 + 1 n_0=n_2+1 n0=n2+1。那么使 n 2 n_2 n2 最大的情况是 n 1 = 0 n_1=0 n1=0。故 n 0 = n + 1 n_0=n+1 n0=n+1。 -
约定一个二叉树的根节点高度为 1 1 1,一颗结点数目为 1020 1020 1020 的二叉树最小高度值为(_____)。
【答案】 10 10 10
【解析】 根据二叉树的第三个性质,推出
1020 ≤ 2 h − 1 1021 ≤ 2 h 2 h ≥ 1021 h ≈ 10 1020\le2^h-1 \\ 1021\le 2^h \\ 2^h\ge1021 \\ h\approx10 1020≤2h−11021≤2h2h≥1021h≈10 -
【NOIP 2016 普及组 T22】 约定二叉树的根节点高度为 1 1 1,一颗结点为 2016 2016 2016 的二叉树最少有(_____)个叶子结点。
【答案】 1 1 1
【解析】 有没有分叉的二叉树,那么最小的叶子结点就为 1 1 1。 -
【NOIP 2014 普及组 T16】 一颗具有 5 5 5 层的满二叉树节点数为(_____)。
【答案】 31 31 31
【解析】 套入公式: n = 2 5 − 1 = 32 − 1 = 31 n=2^5-1=32-1=31 n=25−1=32−1=31。 -
【CSP-J 2022 T12】 独根树的高度为 1 1 1,具有 61 61 61 个结点的完全二叉树的高度为(_____)。
【答案】 6 6 6
【解析】 2 6 − 1 2^6-1 26−1 最接近 61 61 61。 -
【CSP-J 2022 T8】 一颗有 n n n 个结点的完全二叉树用数组进行存储表示,独根树的高度为 1 1 1,若存储在数组第 9 9 9 个位置的结点存储在兄弟结点和两个子结点,则它的兄弟结点和右子结点的位置分别是(_____)。
【答案】 8 19 8\ 19 8 19
【解析】 在 9 9 9 说明是右结点,那么它的兄弟结点为 8 8 8,然后通过套入公式 2 i + 1 = 2 × 9 + 1 = 19 2i+1=2\times9+1=19 2i+1=2×9+1=19,那么它的右子节点的位置就是 19 19 19。 -
【NOIP 2008 普及组 T5】 完全二叉树共有 2 N − 1 2N-1 2N−1 个结点,则它的叶结点数目是(_____)。
【答案】 N N N
【解析】 ⌈ 2 N − 1 2 ⌉ = N \lceil \frac{2N-1}{2} \rceil=N ⌈22N−1⌉=N。 -
一颗完全二叉树上有 1001 1001 1001 个结点,其中叶子结点的个数为(_____)。
【答案】 501 501 501
【解析】 ⌈ 1001 2 ⌉ = 501 \lceil \frac{1001}{2} \rceil=501 ⌈21001⌉=501。
3. 树的遍历
-
【NOIP 2015 普及组 T16】 前序遍历和中序遍历序列相同的二叉树为(_____)。
【答案】 只有根结点的二叉树,或者非叶子结点只有右子树的二叉树 -
【NOIP 2012 普及组 T6】 如果一颗二叉树的中序遍历是 BAC,那么它的先序遍历不可能是(ABC / CBA / ACB / BAC)。
【答案】 ACB
【解析】 我们可以用枚举的方法把所有可能的结果写出来。
三、二叉树的操作
1. 二叉树的存储
二叉树的每个结点都最多只有三条边:父结点、左子树、右子树,所以我们可以用 struct[]
。
2. 二叉树的遍历
中序遍历的代码:
void printInOd(char node)
{
if (l[node]) printInOd(l[node]);
cout << node;
if (r[node]) printInOd(r[node]);
}
后序遍历的代码:
void printInOd(char node)
{
if (l[node]) printInOd(l[node]);
if (r[node]) printInOd(r[node]);
cout << node;
}