C++知识点总结(48):树与二叉树

一、概念

1. 数据结构

一般情况下,我们会将数据结构分为逻辑结构和物理结构,其中逻辑结构是我们的逻辑下存储的结构,而物理结构是计算机的逻辑下存储的结构。数据结构的分类可以参见下表:

数据结构
逻辑结构
非线性结构
集合结构
同属一个集合别无其他关系
树状结构
一对多
图状结构
多对多
线性结构
一对一
物理结构
顺序结构
链式结构
单链表
双链表
循环链表
索引结构
CSP-J不涉及
散列结构

2. 树的基础知识

树是一种非线性的数据结构,由节点和边组成。树是有 n n n n ≥ 0 n \ge 0 n0)个结点组成的具有分支和层次特性的数据集合。

树当中的数据就是 结点

结点的深度:设根节点的深度为 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 m1)个树的集合时,称呼其为 森林
n = 0 n=0 n=0 的时候,树为 空树

如果你看着觉得很花,可以看一看下图:

A-根结点,B和C的父结点
B-A的子结点,D的父结点
C-A的子结点
D-B的子节点,叶结点

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 n1 条边。

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} 2k1 个结点( k ≥ 1 k\ge1 k1)。

性质3: 二叉树的高度为 h h h,则整个二叉树最多有 2 h − 1 2^{h}-1 2h1 个结点( h ≥ 1 h\ge1 h1)。

6. 特殊二叉树

6.1 满二叉树

满二叉树:高度为 h h h 且含有 2 h − 1 2^h-1 2h1 个结点的二叉树(即每个结点都分出两个叉的树)。

满二叉树的编号:编号为 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. 树

  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

  2. 设在一颗度为 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. 二叉树

  1. 【NOIP 2010 普及组 T5】 如果树根算第一层,那么一颗 n n n 层的二叉树最多有(_____)个结点。
    【答案】 2 n − 1 2^n-1 2n1
    【解析】 直接套公式。

  2. 【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

  3. 约定一个二叉树的根节点高度为 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 10202h110212h2h1021h10

  4. 【NOIP 2016 普及组 T22】 约定二叉树的根节点高度为 1 1 1,一颗结点为 2016 2016 2016 的二叉树最少有(_____)个叶子结点。
    【答案】 1 1 1
    【解析】 有没有分叉的二叉树,那么最小的叶子结点就为 1 1 1

  5. 【NOIP 2014 普及组 T16】 一颗具有 5 5 5 层的满二叉树节点数为(_____)。
    【答案】 31 31 31
    【解析】 套入公式: n = 2 5 − 1 = 32 − 1 = 31 n=2^5-1=32-1=31 n=251=321=31

  6. 【CSP-J 2022 T12】 独根树的高度为 1 1 1,具有 61 61 61 个结点的完全二叉树的高度为(_____)。
    【答案】 6 6 6
    【解析】 2 6 − 1 2^6-1 261 最接近 61 61 61

  7. 【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

  8. 【NOIP 2008 普及组 T5】 完全二叉树共有 2 N − 1 2N-1 2N1 个结点,则它的叶结点数目是(_____)。
    【答案】 N N N
    【解析】 ⌈ 2 N − 1 2 ⌉ = N \lceil \frac{2N-1}{2} \rceil=N 22N1=N

  9. 一颗完全二叉树上有 1001 1001 1001 个结点,其中叶子结点的个数为(_____)。
    【答案】 501 501 501
    【解析】 ⌈ 1001 2 ⌉ = 501 \lceil \frac{1001}{2} \rceil=501 21001=501

3. 树的遍历

  1. 【NOIP 2015 普及组 T16】 前序遍历和中序遍历序列相同的二叉树为(_____)。
    【答案】 只有根结点的二叉树,或者非叶子结点只有右子树的二叉树

  2. 【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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值