
第二十一课:树与二叉树基础
------一棵树,为什么会成为计算机最重要的数据结构之一?
本课目标:
看懂树的基本结构;
掌握根、父亲、孩子、兄弟、叶子、度、层次、深度;
理解什么是二叉树;
分清"树"和"二叉树";
掌握满二叉树、完全二叉树;
会计算二叉树的层数、最多结点数;
为下一课"二叉树存储与遍历"打基础。
一、先从"家谱"理解什么是树
我们前面学习:
数组
链表
栈
队列
这些数据结构都有一个共同特点:
数据之间大多是一条线。
例如链表:
A → B → C → D → E
队列:
A → B → C → D
可是现实世界中,有大量的数据不是"一条线"。
例如:
校长
/ \
教师 教师
/ \ |
学生 学生 学生
或者电脑文件夹:
我的电脑
├── 学习
│ ├── C++
│ ├── 数学
│ └── 英语
├── 游戏
│ ├── 游戏A
│ └── 游戏B
└── 图片
├── 风景
└── 家庭
这种:
一层一层向下分支
的结构,就是:
树(Tree)
讲义指出,树特别适合表示"元素之间具有分支层次关系的数据"。
二、为什么叫"树"?
现实中的树:
树干
│
┌─┴─┐
│ │
树枝 树枝
/ \ \
叶 叶 叶
数据结构里的树:
A
/ | \
B C D
/ \ |
E F G
看起来是不是非常像?
所以计算机科学家就把这种结构叫:
Tree------树
不过要注意:
数据结构中的"树"通常画成根在上面、枝叶在下面。
和自然界的树倒过来。
三、树最重要的一个概念:结点
显然树并不是一根自然界的树。
C++中,它由一个一个:
结点(Node)
组成。
例如:
A
/ \
B C
/ \
D E
这里:
A、B、C、D、E
都是结点。
我们对树结点的描述是:
一个结点包含一个数据元素,以及若干个指向其子树的分支。
所以大家可以简单理解成:
一个结点 + 它下面连接出去的若干个结点。
四、认识"根结点"
一棵树最上面的结点:
A
/ \
B C
A叫:
根结点(Root)
它有一个非常重要的特点:
根结点没有父亲。
就像家谱中的"祖先"。
五、认识父亲和孩子
看这棵树:
A
/ \
B C
/ \
D E
对于B来说:
A是B的父结点
对于A来说:
B、C是A的孩子
对于D来说:
B是D的父结点
所以:
A
↓
B
↓
D
可以理解成:
爷爷
↓
爸爸
↓
孩子
我们分别定义了孩子结点和双亲结点。
六、兄弟是什么?
还是:
A
/ \
B C
/ \
D E
B和C:
父亲都是A
所以:
B和C是兄弟。
D和E:
父亲都是B
所以:
D和E也是兄弟。
具有同一父结点的子结点互称兄弟。
七、什么是叶子结点?
这是CSP-J特别喜欢考的概念。
看:
A
/ \
B C
/ \
D E
D没有孩子。
E没有孩子。
C也没有孩子。
所以:
D、E、C
都是:
叶子结点
也叫:
终端结点
度为0的结点,就是叶子结点。
记住一句话:
下面没人了,就是叶子。
八、什么是分支结点?
反过来:
只要一个结点:
还有孩子
它就是:
分支结点
也叫:
非终端结点
例如:
A
/ \
B C
/ \
D E
A和B有孩子:
A、B
所以:
A、B = 分支结点
C、D、E = 叶子结点
我们就是按照"度大于0"为分支结点、"度为0"为叶子结点来定义的。
九、什么叫"结点的度"?
这是本课第一个重点。
一个结点的:
度 = 它有多少个孩子
例如:
A
/ | \
B C D
A有:
B、C、D
三个孩子。
所以:
A的度 = 3
再看:
B
/ \
E F
B有两个孩子:
B的度 = 2
而:
C
没有孩子:
C的度 = 0
我们给出的定义就是:
结点的度 = 一个结点拥有的子树数目。
十、树的度又是什么?
这里特别容易混。
假设:
A
/ | \
B C D
/ \
E F
各结点:
A:3
B:2
C:0
D:0
E:0
F:0
那么:
最大的度 = 3
因此:
这棵树的度 = 3
也就是说:
结点的度:看一个结点。
树的度:看整棵树,取最大值。
是这样定义的。
十一、一个容易错的题
如果:
A有3个孩子
B有2个孩子
C有1个孩子
D没有孩子
问:
树的度是多少?
很多孩子会回答:
3+2+1=6
这是错误的。
树的度是:
max(3,2,1,0)
= 3
所以答案:
3
十二、什么是层次?
现在看:
A
/ \
B C
/ \
D E
我们的定义:
根结点的层次 = 1
所以:
A:第1层
B:第2层
C:第2层
D:第3层
E:第3层
本课定义:
结点的层次 = 从根结点到该结点所经过的路径长度 + 1。
所以采用的是:
根结点层次 = 1
这一点一定要特别提醒大家。
有时算法教材也可能定义:
根的深度 = 0
而我们本课讨论树的层次时使用:
根 = 第1层
初赛做题一定要以题目定义为准。
十三、什么是树的深度?
如果:
A:第1层
B、C:第2层
D、E:第3层
那么最深的一层是:
第3层
所以:
树的深度 = 3
树的深度为:
树中叶子结点具有的最大层次数。
简单记:
最深的叶子在哪一层,树的深度就是多少。
十四、路径是什么?
例如:
A
|
B
|
D
从A到D:
A → B → D
这条路线就是:
路径
我们将路径定义为,从根到结点所经过的分支和结点构成的序列。
大家可以把它理解成:
从树根走到某个结点的路线。
十五、祖先和子孙
看:
A
/
B
/
D
/
G
对于G:
A、B、D
都是G的:
祖先
而G是:
A、B、D
的:
子孙
十六、到这里,我们把树的术语串起来
给大家画这样一张图:
A
/ | \
B C D
/ \
E F
请问:
A是什么?
根结点
B、C、D是什么?
A的孩子
B和C是什么关系?
兄弟
E和F是什么关系?
兄弟
B的父结点?
A
E的父结点?
B
E的度?
0
B的度?
2
A的度?
3
整棵树的度?
3
叶子?
C、D、E、F
这就是我们要必须掌握的基本功。
十七、接下来进入本课重要的主角:二叉树
现在我们把刚才的树限制一下:
每个结点最多只能有两个孩子。
这时候就变成:
二叉树(Binary Tree)
例如:
A
/ \
B C
/ \
D E
每个结点:
最多2个孩子
所以是二叉树。
二叉树的定义:
二叉树是由根结点以及左子树和右子树组成的有限集合;每个结点至多只有两棵子树。
十八、为什么叫"二叉"?
"二"很好理解:
最多两个孩子
"叉"可以理解成:
一个地方最多分成两条路
所以:
A
/ \
B C
就是:
A
/ \
左 右
十九、二叉树最重要的特点:左右不能乱换
这是二叉树与普通树最容易混淆的地方。
看:
A
/ \
B C
在二叉树中:
B = 左孩子
C = 右孩子
如果交换:
A
/ \
C B
这是:
另一棵二叉树
因为:
二叉树有左、右之分。
特别强调:
二叉树的子树有左右之分,其次序不能任意颠倒。
二十、普通树和二叉树有什么区别?
这是初赛选择题经常考的概念。
普通树
一个结点可以有:
0个
1个
2个
3个
4个
......
孩子。
例如:
A
/ / \ \
B C D E
完全可以。
二叉树
一个结点最多:
2个孩子
例如:
A
/ \
B C
但:
A
/ | \
B C D
就不是二叉树。
总结:
普通树中结点最大度数没有限制,而二叉树结点最大度数为2;普通树没有左、右之分,而二叉树有左、右之分。
二十一、一个经典的思考题:3个结点有几种二叉树?
我们提出这个问题:
具有3个结点的二叉树可能有5种不同形态。
我们来数一数。
第一种
A
/
B
/
C
第二种
A
/
B
\
C
第三种
A
\
B
/
C
第四种
A
\
B
\
C
第五种
A
/ \
B C
所以:
5种
为什么不是3种?
因为:
二叉树有"左"和"右"的区别。
这就是二叉树非常重要的特征。
二十二、什么是满二叉树?
接下来是初赛高频考点。
先画一棵:
A
/ \
B C
/ \ / \
D E F G
你会发现:
每一个非叶子结点
都有两个孩子
而且:
每一层都排得满满的。
这就是:
满二叉树
定义是:
深度为 k 且有 2^k-1 个结点的二叉树。每一层的结点数都是该层的最大值。
这里采用讲义的层数定义:
深度 = k
那么:
第1层:1
第2层:2
第3层:4
第4层:8
总数:
1 + 2 + 4 + 8 + ...
最终:
2^k - 1
二十三、为什么是 2^k-1?
例如深度:
k = 1
只有:
1
而:
2¹ - 1 = 1
正确。
深度:
k = 2
有:
1
2
一共:
3
而:
2² - 1 = 3
深度:
k = 3
有:
1
2
4
总共:
7
而:
2³ - 1 = 7
二十四、什么是完全二叉树?
完全二叉树非常重要。
例如:
A
/ \
B C
/ \ /
D E F
它虽然不是满二叉树,因为:
C只有左孩子
但是它仍然是:
完全二叉树
为什么?
因为:
上面的层都填满,最后一层从左向右连续排列,中间不能出现空洞。
完全二叉树的定义是:将完全二叉树与同深度的满二叉树编号1到n的结点逐一对应;
其特点是至多只有最下面两层的结点度可能小于2,而且倒数第二层如果只有一个孩子,必须是左孩子。
二十五、满二叉树和完全二叉树到底差在哪里?
这是初学者容易混淆的地方。
满二叉树
要求非常严格:
每一层都满
例如:
A
/ \
B C
/ \ / \
D E F G
完全二叉树
允许最后一层:
从右边开始缺一些。
例如:
A
/ \
B C
/ \ /
D E F
可以。
但:
A
/ \
B C
/ \
D E
不可以。
因为最后一层出现了:
D 空 F?
中间有空洞。
二十六、一个特别好用的判断方法
给孩子一句口诀:
完全二叉树:最后一层必须"左对齐"。
也就是说:
√ √ √ √ 空 空
可以。
√ √ √ 空 空 空
可以。
但:
√ 空 √ √
不可以。
因为出现了:
"左边空了,右边还有人"。
二十七、满二叉树是完全二叉树吗?
答案:
当然是!
满二叉树是完全二叉树的一个特例。
所以关系是:
二叉树
│
┌────┴────┐
↓ ↓
完全二叉树 其他二叉树
│
↓
满二叉树
更准确地说:
满二叉树 ⊂ 完全二叉树 ⊂ 二叉树
二十八、二叉树第i层最多有多少个结点?
二叉树的性质1。
如果根是第1层:
第1层:1
第2层:2
第3层:4
第4层:8
所以:
第i层最多有 2^(i-1) 个结点
要掌握这一性质。
二十九、为什么是 2^(i-1)?
因为:
第1层
1 = 2⁰
第2层
2 = 2¹
第3层
4 = 2²
第4层
8 = 2³
所以:
第i层
= 2^(i-1)
三十、初赛题:第8层最多多少个结点?
直接套:
2^(8-1)
= 2^7
= 128
答案:
128
这种题不要再画树了。
直接上公式。
三十一、深度为k的满二叉树有多少个结点?
刚才已经推出来:
第1层:1
第2层:2
第3层:4
......
第k层:2^(k-1)
总数:
1 + 2 + 4 + ... + 2^(k-1)
等比数列:
= 2^k - 1
所以:
满二叉树结点数 = 2^k-1
三十二、完全二叉树有多少个结点?
如果深度为:
k
那么:
最少
前面层数尽量少,只有最后一层一个结点:
1
2
4
...
2^(k-2)
1
讲义给出的结论是:
深度为 k 的完全二叉树,至少有 2^(k-1) 个结点,最多有 2^k-1 个结点。
所以:
最少:2^(k-1)
最多:2^k - 1
三十三、举个例子
如果:
k = 4
完全二叉树最少:
2^(4-1)
= 8
最多:
2^4 - 1
= 15
所以:
8 ≤ n ≤ 15
三十四、一道经典的选择题
题目:
一棵完全二叉树有1001个结点,问叶子结点个数。
这里实际上可以利用一个重要规律:
对于一棵二叉树,如果:
n0 = 度为0的结点数
n1 = 度为1的结点数
n2 = 度为2的结点数
则:
n0 = n2 + 1
这个结论我们可以放到下一阶段继续重点推导。
对于完全二叉树,还可以利用:
编号从1开始时,编号大于 n/2 的结点都是叶子。
这个结论后面讲二叉树顺序存储时会重点解释。
三十五、对于我们小学生,先建立:
形状 → 规律 → 公式
而不是:
公式 → 死记
比如:
●
/ \
● ●
/ \ / \
● ●● ●
先看到:
1
2
4
再想到:
2^(i-1)
然后自然得到:
1+2+4+...=2^k-1
这样孩子以后遇到陌生题也不会慌。
方法一:利用完全二叉树的编号
完全二叉树从上到下、从左到右编号:
1
/ \
2 3
/ \ / \
4 5 6 7
...
对于有 n 个结点的完全二叉树:
编号大于 ⌊n/2⌋ \lfloor 的结点全部是叶子结点。
这里:
n=1001
所以:
⌊1001/2⌋=500
因此:
1 ~ 500 非叶子结点
501 ~ 1001 叶子结点
叶子数量:
1001−500=501
正确答案是:
501 个
方法二:从"最后一层"理解
1001 个结点的完全二叉树:
前面的 500 个结点可以看成:
1 ~ 500
它们负责产生孩子。
从:
501 ~ 1001
开始的结点没有孩子,因此全部是叶子。
数量:
1001−500=501
所以答案是:
501
记忆口诀:
完全二叉树,从 n/2 + 1开始,全是叶子。
三十六、CSP-J最喜欢考的"概念陷阱"
陷阱1:树的度
错误:
所有结点度数加起来
正确:
最大结点度数
陷阱2:叶子结点
错误:
最下面一层所有结点
正确:
度为0的结点
陷阱3:二叉树必须有两个孩子
错误。
二叉树是:
最多两个
可以:
0个
1个
2个
陷阱4:完全二叉树必须每个结点都有两个孩子
错误。
例如:
A
/ \
B C
/
D
完全二叉树可以存在一个孩子。
陷阱5:满二叉树和完全二叉树一样
错误。
关系:
满二叉树
↓
一定是
↓
完全二叉树
但反过来:
完全二叉树
↓
不一定
↓
满二叉树
三十七、课堂小测①
给出:
A
/ | \
B C D
/ \
E F
问:
1. A的度?
3
2. B的度?
2
3. C的度?
0
4. 这棵树的度?
3
5. 叶子有哪些?
C、D、E、F
6. B和C是什么关系?
兄弟
三十八、课堂小测②:判断是不是二叉树
A
A
/ \
B C
是。
B
A
/|\
B C D
不是二叉树。
因为:
A有3个孩子。
三十九、课堂小测③:判断是不是完全二叉树
图1
A
/ \
B C
/ \ /
D E F
答案:
是
图2
A
/ \
B C
/ \
D E
答案:
不是
因为最后一层不满足从左向右连续排列。
四十、课堂小测④:计算
一棵二叉树第5层最多有多少个结点?
2^(5-1)
= 16
答案:
16
四十一、课堂小测⑤:满二叉树
一棵深度为5的满二叉树有多少个结点?
2^5 - 1
= 31
答案:
31
四十二、把本课知识画成一张地图
树
│
┌──────────┴──────────┐
↓ ↓
普通树 二叉树
孩子数不限 最多2个孩子
│
┌───────┴───────┐
↓ ↓
完全二叉树 其他
│
↓
满二叉树
树的基本术语:
根
│
├── 父结点
├── 孩子
├── 兄弟
├── 祖先
├── 子孙
├── 叶子:度=0
├── 分支结点:度>0
├── 结点的度:孩子数量
└── 树的度:所有结点度的最大值
二叉树:
第i层最多:
2^(i-1)
深度k的满二叉树:
2^k - 1
深度k的完全二叉树:
2^(k-1) ≤ n ≤ 2^k - 1
四十三、本课要让同学们掌握的5个概念
① 什么是树?
树是一种具有层次和分支关系的数据结构。
② 什么是二叉树?
每个结点最多有两个孩子,而且有左、右之分。
③ 什么是叶子?
没有孩子的结点,度为0。
④ 什么是完全二叉树?
除了最后一层外,上面各层都是满的,最后一层从左向右连续排列。
⑤ 满二叉树和完全二叉树什么关系?
满二叉树一定是完全二叉树,但完全二叉树不一定是满二叉树。
四十四、本课与CSP-J初赛的连接
这一课虽然看起来"只是概念",实际上是后面大量初赛题目的基础。
在树和二叉树习题中,有大量:
-
树的度;
-
结点的度;
-
叶子结点;
-
完全二叉树叶子数;
-
二叉树某一层最多结点数;
-
二叉树最少结点数;
-
前序、中序、后序遍历;
-
完全二叉树高度;
-
二叉树顺序存储编号。
例如直接考查"第 i 层最多有多少结点"、完全二叉树结点数量,以及根据遍历序列还原二叉树。
所以我们要把"树的语言"学会。否则到了后面看到:
tree[x].left
tree[x].right
或者:
dfs(root)
大家会觉得每一个词都很陌生。
四十五、本课作业
画5棵不同的树,每棵树同学们都要回答:
① 根结点是谁?
② 有多少个结点?
③ 哪些是叶子?
④ 哪些是分支结点?
⑤ 某结点的度是多少?
⑥ 整棵树的度是多少?
⑦ 某结点在哪一层?
⑧ 树的深度是多少?
⑨ 是不是二叉树?
⑩ 是不是完全二叉树?
⑪ 是不是满二叉树?
尤其最后的三问一定要反复练。