← Back to Learning Notes

Lecture 16:二叉树常考性质

Chinese-language Computer Science 408 note: Lecture 16:二叉树常考性质. Original source available where applicable.

On this page

This note is currently available in Chinese. The original wording, formulas and diagrams are preserved to avoid an unverified technical translation.

16.1 二叉树的定义和基本术语

16.1.1 二叉树的基本概念

定义:#二叉树

描述: 二叉树是 $n(n\ge 0)$ 个结点的有限集合。它要么是空二叉树,要么由一个根结点和两棵互不相交的二叉树组成,这两棵二叉树分别称为根的左子树和右子树。

两种二叉树

  • 空二叉树: $$ n=0 $$

  • 非空二叉树:

    • 有且仅有一个根结点。
    • 根结点可以有左子树。
    • 根结点可以有右子树。
    • 左子树和右子树本身仍然是二叉树。
    • 左右子树互不相交。

特点

  1. 每个结点至多只有两棵子树。
  2. 左子树和右子树不能颠倒,因此二叉树是有序树。
  3. 二叉树可以为空;二叉树为空只表示没有结点,不表示这种二叉树不存在。
  4. 二叉树不是“度为 $2$ 的有序树”的简单别名。

二叉树与度为 2 的有序树的区别

对比项 二叉树 度为 $2$ 的有序树
是否允许为空 允许为空 通常不讨论空树
是否必须存在度为 $2$ 的结点 不要求 至少有一个结点度为 $2$
只有一个孩子时是否区分左右 区分左孩子和右孩子 按有序树子树次序理解
每个结点最多孩子数 $2$ $2$

解释

  • “二叉树有序”指的是左、右位置本身有含义。
  • 一个结点只有一个孩子时,必须说明它是左孩子还是右孩子。
  • 两棵树形状看起来相似,但左右位置不同,也可能是两棵不同的二叉树。

DS-L16-二叉树递归结构.png

读图说明

  • 以 A 为根的二叉树由 A、左子树和右子树递归构成,两棵子树互不相交。
  • 以 B 为根的示例只有左子树,右子树是空二叉树;这与“没有右子树位置”不同,左右位置仍然有意义。

16.1.2 常见二叉树

满二叉树

定义:#满二叉树

描述: 一棵高度为 $h$,且含有 $2^h-1$ 个结点的二叉树,称为满二叉树。

核心公式 $$ n=2^h-1 $$

特点

  1. 只有最后一层有叶子结点。
  2. 不存在度为 $1$ 的结点。
  3. 所有非叶结点的度都为 $2$。
  4. 若按层序从 $1$ 开始编号,则编号关系为: $$ \text{左孩子}=2i $$ $$ \text{右孩子}=2i+1 $$ $$ \text{父结点}=\left\lfloor \frac{i}{2}\right\rfloor $$

记忆

  • 满二叉树的每一层都被填满。
  • 高度为 $h$ 时,第 $h$ 层有 $2^{h-1}$ 个叶子结点。
  • 前 $h$ 层结点总数是等比数列和: $$ 1+2+4+\cdots+2^{h-1}=2^h-1 $$

DS-L16-满二叉树层序编号.png

读图说明

  • 图中每层都达到容量上限,按层序编号后,结点 $i$ 的左右孩子分别位于 $2i$ 和 $2i+1$;第四层编号为 $8\sim15$。

完全二叉树

定义:#完全二叉树

描述: 当且仅当一棵二叉树的每个结点都与高度为 $h$ 的满二叉树中编号为 $1\sim n$ 的结点一一对应时,称为完全二叉树。

直观理解

  • 从一棵满二叉树开始。
  • 按层序编号。
  • 只允许从编号最大的结点开始连续删除。
  • 删除后剩下的树就是完全二叉树。

特点

  1. 只有最后两层可能有叶子结点。
  2. 最多只有一个度为 $1$ 的结点。
  3. 若按层序从 $1$ 开始编号,结点 $i$ 的关系为: $$ \text{左孩子}=2i $$ $$ \text{右孩子}=2i+1 $$ $$ \text{父结点}=\left\lfloor\frac{i}{2}\right\rfloor $$
  4. 结点编号满足: $$ i\le \left\lfloor\frac{n}{2}\right\rfloor $$ 则结点 $i$ 为分支结点。 $$ i> \left\lfloor\frac{n}{2}\right\rfloor $$ 则结点 $i$ 为叶子结点。
  5. 如果某个结点只有一个孩子,那么这个孩子一定是左孩子。

为什么只有一个孩子时一定是左孩子

  • 完全二叉树按从上到下、从左到右的顺序填充。
  • 不可能出现“右孩子存在而左孩子不存在”的情况。
  • 若某个结点只有一个孩子,说明最后一层填充到该结点的左孩子就停止了。

DS-L16-完全二叉树形态.png

读图说明

  • 实线和彩色结点是当前完全二叉树,浅色虚线结点表示满二叉树中尚未占用的位置。
  • 现有结点编号连续为 $1\sim12$;若出现编号 $13$ 而编号 $12$ 不存在,就不再是完全二叉树。

二叉排序树

定义:#二叉排序树

描述: 二叉排序树是一种可用于元素排序和搜索的二叉树。

特征

  1. 左子树上所有结点的关键字均小于根结点的关键字。
  2. 右子树上所有结点的关键字均大于根结点的关键字。
  3. 左子树和右子树又各是一棵二叉排序树。

上述写法默认关键字互不相同。若允许重复关键字,必须预先约定重复项统一放在一侧或在结点中记录计数,不能时左时右。

递归理解

  • 根结点把数据分成两部分。
  • 小于根的都放左边。
  • 大于根的都放右边。
  • 左右子树内部继续满足同样规则。

中序遍历性质

  • 对二叉排序树进行中序遍历,可以得到递增序列。
  • 这一性质是后续查找、插入、删除和排序题的重要基础。

DS-L16-BST与AVL约束.png

读图说明

  • 左半部分以 19 为根,左子树所有关键字都小于 19,右子树所有关键字都大于 19,而且两棵子树递归满足同样条件。
  • 右半部分展示一个局部平衡的二叉排序树;AVL 的平衡条件必须对树中每个结点都成立。

平衡二叉树

定义:#平衡二叉树

描述: 408 语境中的平衡二叉树通常指 AVL 树:它首先是一棵二叉排序树,并且树上任一结点的左、右子树高度之差的绝对值不超过 $1$。

公式化表达 对任意结点 $x$,都有: $$ \left|h_L(x)-h_R(x)\right|\le 1 $$

其中:

  • $h_L(x)$ 表示结点 $x$ 左子树高度。
  • $h_R(x)$ 表示结点 $x$ 右子树高度。

注意

  • 只满足高度差条件而不满足二叉排序树关键字次序的普通二叉树,不是 AVL 树。
  • 平衡二叉树强调任意结点,而不仅仅是根结点。
  • 只看根的左右高度差不够,子树内部也必须平衡。

16.2 二叉树的性质

16.2.1 最常用性质

性质一:第 k 层最多结点数

二叉树第 $k$ 层最多有: $$ 2^{k-1} $$ 个结点。

说明

  • 根结点位于第 $1$ 层。
  • 第 $1$ 层最多 $1=2^0$ 个结点。
  • 第 $2$ 层最多 $2=2^1$ 个结点。
  • 第 $3$ 层最多 $4=2^2$ 个结点。
  • 依次类推,第 $k$ 层最多 $2^{k-1}$ 个结点。

性质二:叶子结点数与二分支结点数

设非空二叉树中:

  • $n_0$ 表示度为 $0$ 的结点数,即叶子结点数。
  • $n_1$ 表示度为 $1$ 的结点数。
  • $n_2$ 表示度为 $2$ 的结点数。

则: $$ n_0=n_2+1 $$

含义

  • 叶子结点永远比分支数为 $2$ 的结点多 $1$ 个。
  • 这个结论与 $n_1$ 的数量无关。

性质三:高度为 h 的二叉树最多结点数

高度为 $h$ 的二叉树最多有: $$ 2^h-1 $$ 个结点。

达到最大值的情况

  • 每一层都达到最大结点数。
  • 树必须是满二叉树。

性质四:二叉树高度范围

含 $n\ge 1$ 个结点的二叉树,高度 $h$ 的范围为: $$ \left\lfloor\log_2 n\right\rfloor+1\le h\le n $$

等价地,最小高度也可以写成: $$ \left\lceil\log_2(n+1)\right\rceil $$

解释

  • 最矮的情况:尽量填满每一层,形态接近完全二叉树。
  • 最高的情况:每个结点都只有一个孩子,退化成单支链。

性质五:二叉链表空指针总数

若一棵二叉树有 $n$ 个结点,则二叉链表中共有: $$ 2n $$ 个指针域。

其中有 $n-1$ 个指针指向真实结点,因此空指针数为: $$ 2n-(n-1)=n+1 $$

PDF 中的另一种推导 按结点度数拆分: $$ \text{空指针数}=2n_0+n_1 $$

又因为: $$ n=n_0+n_1+n_2 $$ $$ n_0=n_2+1 $$

所以: $$ 2n_0+n_1=n_0+n_0+n_1=n_0+n_2+1+n_1=n+1 $$

16.2.2 二叉树的常考性质

考点一:$n_0=n_2+1$

设非空二叉树中度为 $0,1,2$ 的结点个数分别为 $n_0,n_1,n_2$。

结论 $$ n_0=n_2+1 $$

推导 第一种计数方式:按结点的度分类。 $$ n=n_0+n_1+n_2 $$

第二种计数方式:结点数等于总度数加 $1$。 $$ n=n_1+2n_2+1 $$

两式相减: $$ n_0+n_1+n_2=n_1+2n_2+1 $$

整理得到: $$ n_0=n_2+1 $$

为什么结点数等于总度数加 1

  • 所有结点的度数之和等于边数。
  • 非空树中,边数为结点数减 $1$。
  • 因此: $$ \text{总度数}=n-1 $$ $$ n=\text{总度数}+1 $$

考点二:每层结点数

二叉树第 $i$ 层至多有: $$ 2^{i-1} $$ 个结点,其中: $$ i\ge 1 $$

$m$ 叉树第 $i$ 层至多有: $$ m^{i-1} $$ 个结点,其中: $$ i\ge 1 $$

对比

树类型 第 $i$ 层最多结点数
二叉树 $2^{i-1}$
$m$ 叉树 $m^{i-1}$

考点三:高度为 h 的树最多结点数

高度为 $h$ 的二叉树至多有: $$ 2^h-1 $$ 个结点。

当 $m\ge 2$ 时,高度为 $h$ 的 $m$ 叉树至多有: $$ \frac{m^h-1}{m-1} $$ 个结点。

当 $m=1$ 时,树退化为链,最多有 $h$ 个结点。

推导 $m$ 叉树每层最多结点数为: $$ 1,m,m^2,\cdots,m^{h-1} $$

求和: $$ 1+m+m^2+\cdots+m^{h-1}=\frac{m^h-1}{m-1} $$

16.2.3 完全二叉树的常考性质

考点一:n 个结点的完全二叉树高度

具有 $n(n>0)$ 个结点的完全二叉树高度 $h$ 为: $$ h=\left\lceil\log_2(n+1)\right\rceil $$

也可以写为: $$ h=\left\lfloor\log_2 n\right\rfloor+1 $$

两种写法为什么都可以

  • $\left\lceil\log_2(n+1)\right\rceil$ 是从“满到第 $h$ 层至少需要覆盖 $n$ 个结点”推出来的。
  • $\left\lfloor\log_2 n\right\rfloor+1$ 是由最大编号 $n$ 所在层数推出来的。
  • 二者对正整数 $n$ 等价。

推导思路 高度为 $h$ 的完全二叉树满足: $$ 2^{h-1}\le n\le 2^h-1 $$

由左边: $$ h\le \log_2 n+1 $$

由右边: $$ n+1\le 2^h $$ $$ \log_2(n+1)\le h $$

因此: $$ h=\left\lceil\log_2(n+1)\right\rceil $$

考点二:由 n 推出 $n_0,n_1,n_2$

完全二叉树最多只有一个度为 $1$ 的结点,因此: $$ n_1=0\ \text{或}\ 1 $$

又因为: $$ n_0=n_2+1 $$

所以: $$ n_0+n_2 $$ 一定是奇数。

情况一:结点总数为偶数 若完全二叉树有 $2k$ 个结点,则必有: $$ n_1=1 $$ $$ n_0=k $$ $$ n_2=k-1 $$

推导 $$ n=n_0+n_1+n_2 $$

代入 $n=2k$ 和 $n_0=n_2+1$: $$ 2k=(n_2+1)+n_1+n_2 $$

若 $n_1=1$: $$ 2k=2n_2+2 $$ $$ n_2=k-1 $$ $$ n_0=k $$

情况二:结点总数为奇数 若完全二叉树有 $2k-1$ 个结点,则必有: $$ n_1=0 $$ $$ n_0=k $$ $$ n_2=k-1 $$

推导 $$ 2k-1=(n_2+1)+0+n_2 $$ $$ 2k-1=2n_2+1 $$ $$ n_2=k-1 $$ $$ n_0=k $$

速记表

完全二叉树结点总数 $n_1$ $n_0$ $n_2$
$2k$ $1$ $k$ $k-1$
$2k-1$ $0$ $k$ $k-1$

完全二叉树性质补充

对完全二叉树按层序从 $1$ 开始编号,设结点总数为 $n$。

父结点编号

当 $i>1$ 时,结点 $i$ 的双亲编号为: $$ \left\lfloor\frac{i}{2}\right\rfloor $$

奇偶关系

  • 当 $i$ 为偶数时: $$ \text{父结点编号}=\frac{i}{2} $$ 此时 $i$ 是双亲的左孩子。

  • 当 $i$ 为奇数时: $$ \text{父结点编号}=\frac{i-1}{2} $$ 此时 $i$ 是双亲的右孩子。

左孩子编号

当: $$ 2i\le n $$ 时,结点 $i$ 的左孩子编号为: $$ 2i $$

否则结点 $i$ 没有左孩子。

右孩子编号

当: $$ 2i+1\le n $$ 时,结点 $i$ 的右孩子编号为: $$ 2i+1 $$

否则结点 $i$ 没有右孩子。

结点 i 所在层次

结点 $i$ 所在层次为: $$ \left\lfloor\log_2 i\right\rfloor+1 $$

注意区分

  • 求“编号 $i$ 的结点所在层次”,用 $i$: $$ \left\lfloor\log_2 i\right\rfloor+1 $$

  • 求“$n$ 个结点的完全二叉树高度”,用 $n$: $$ \left\lceil\log_2(n+1)\right\rceil $$ 或: $$ \left\lfloor\log_2 n\right\rfloor+1 $$

16.3 二叉树的存储结构

16.3.1 顺序存储

定义:#顺序存储

描述: 二叉树的顺序存储用数组 t 按对应满二叉树的层序编号存放结点。若最大结点编号为 MaxSize,并约定 t[0] 留空,则数组至少需要 MaxSize+1 个槽位。

重要结论

  • 二叉树的顺序存储结构特别适合完全二叉树,因为结点编号与数组位置连续对应。
  • 其他二叉树也可以按其在对应完全二叉树中的位置补空位存储,但可能严重浪费空间。
  • 对于非完全二叉树,必须把结点编号与对应位置补齐,否则无法直接用编号关系判断父子关系。

数组下标习惯

  • PDF 中为了让结点编号和数组下标一致,通常让 t[0] 空出来。
  • 这样编号为 $i$ 的结点就放在 t[i] 中。

基本操作 对完全二叉树,结点 $i$:

  • 左孩子编号: $$ 2i $$

  • 右孩子编号: $$ 2i+1 $$

  • 父结点编号: $$ \left\lfloor\frac{i}{2}\right\rfloor $$

  • 若求结点 $i$ 所在层次: $$ \left\lfloor\log_2 i\right\rfloor+1 $$

  • 若求 $n$ 个结点的完全二叉树高度: $$ \left\lceil\log_2(n+1)\right\rceil $$ 或: $$ \left\lfloor\log_2 n\right\rfloor+1 $$

基本判断操作

  • 判断 $i$ 是否有左孩子: $$ 2i\le n $$

  • 判断 $i$ 是否有右孩子: $$ 2i+1\le n $$

  • 判断 $i$ 是否为叶子结点: $$ i>\left\lfloor\frac{n}{2}\right\rfloor $$

  • 判断 $i$ 是否为分支结点: $$ i\le\left\lfloor\frac{n}{2}\right\rfloor $$

非完全二叉树的顺序存储问题

  • 非完全二叉树的结点编号无法和真实结点连续对应。
  • 顺序存储时,必须把该二叉树的结点编号与完全二叉树中的位置对应起来。
  • 空缺位置需要显式标记为空。
  • 不能只通过 $i$ 和 $n$ 的大小关系判断是否有左、右孩子。
  • 需要使用 isEmpty 属性判断某个数组位置是否为空。

最坏情况

  • 高度为 $h$ 且只有 $h$ 个结点的右单支树,最深结点编号为: $$ 2^h-1 $$
  • 为保留编号 $1\sim 2^h-1$ 的位置,需要 $2^h-1$ 个有效编号位置;若还让 t[0] 留空,实际数组至少需要 $2^h$ 个槽位。空缺位置以 isEmpty 标记。

结论

  • 顺序存储特别适合完全二叉树,但并非不能存储其他二叉树。
  • 对非完全二叉树可能严重浪费空间。
  • 对非完全二叉树,判断空结点必须依赖 isEmpty。

DS-L16-完全二叉树顺序存储.png

完全二叉树读图

  • t[0] 留空后,结点编号与数组下标一致,编号 $1\sim12$ 的结点连续占用 t[1] 至 t[12]。

DS-L16-非完全二叉树顺序存储.png

非完全二叉树读图

  • 右单支树只有 1、3、7、15 四个结点,却必须保留编号对应的空位;高度为 $4$ 时已经占到 t[15],体现了最坏情况下的空间浪费。

顺序存储代码实现

#include <stdbool.h>

#define MaxSize 100
typedef int ElemType;  // 示例元素类型,可替换

typedef struct {
    ElemType value;  // 结点中的数据元素
    bool isEmpty;   // 结点是否为空
} TreeNode;

// 初始化数组
TreeNode t[MaxSize + 1];  // t[0] 留空,可用编号为 1~MaxSize

void InitTreeArray(TreeNode t[]) {
    for (int i = 0; i <= MaxSize; i++) {
        t[i].isEmpty = true;
    }
}

代码理解

  • value 保存结点数据。
  • isEmpty 用来标记该数组位置是否为空。
  • 对非完全二叉树尤其需要 isEmpty,否则无法区分“该位置没有结点”和“数组没有用到”。
  • 访问 t[i] 前仍须保证 $1\le i\le\texttt{MaxSize}$;isEmpty 不能代替数组越界检查。

16.3.2 链式存储

定义:#链式存储

描述: 二叉树的链式存储用结点和指针表示树中结点之间的父子关系,每个结点通常包含数据域、左孩子指针和右孩子指针。

二叉链表结点结构

  • 数据域:保存结点自身数据。
  • 左孩子指针:指向左孩子。
  • 右孩子指针:指向右孩子。

空链域数量 若非空二叉树有 $n$ 个结点:

  • 每个结点有 $2$ 个指针域。

  • 总指针域数为: $$ 2n $$

  • 除根结点外,每个结点都有一个来自父结点的指针,因此非空指针数为: $$ n-1 $$

  • 空指针域数为: $$ 2n-(n-1)=n+1 $$

作用

  • 这些空链域后续可以用于构造线索二叉树。
  • 链式存储对非完全二叉树更节省空间。

DS-L16-二叉链表结构.png

读图说明

  • 左图突出真实存在的结点,浅色位置不分配链式结点;右图每个结点只用 lchild、rchild 指向实际孩子,空孩子对应 NULL。
  • 链式结构不需要为完全二叉树编号中的空位预留结点,因此更适合形态稀疏的二叉树。

结点定义

// 二叉树的结点(链式存储)
typedef struct BiTNode {
    ElemType data;                  // 数据域
    struct BiTNode *lchild, *rchild; // 左、右孩子指针
} BiTNode, *BiTree;

解释

  • BiTNode 表示一个二叉树结点类型。
  • BiTree 表示指向二叉树根结点的指针。
  • 若 BiTree root = NULL;,表示这是一棵空二叉树。

链式树构建示例

// 二叉树的链式构建
#include <stdlib.h>

typedef struct {
    int value;
} ElemType;

typedef struct BiTNode {
    ElemType data;
    struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

void LinkTreeExample(void) {
    // 定义一棵空树,root 指向根结点
    BiTree root = NULL;

    // 插入根结点
    root = malloc(sizeof *root);
    if (root == NULL) return;
    root->data = (ElemType){1};
    root->lchild = NULL;
    root->rchild = NULL;

    // 插入新结点
    BiTNode *p = malloc(sizeof *p);
    if (p == NULL) {
        free(root);
        return;
    }
    p->data = (ElemType){2};
    p->lchild = NULL;
    p->rchild = NULL;
    root->lchild = p;  // 作为根结点的左孩子

    // 示例结束后释放;实际使用时应在树不再需要时释放
    free(p);
    free(root);
}

构建过程

  1. root = NULL 表示原来是空树;构建语句须写在函数体内。
  2. malloc(sizeof(BiTNode)) 为根结点申请空间。
  3. 给根结点的数据域赋值。
  4. 根结点的左、右孩子指针先置为 NULL。
  5. 再申请一个新结点 p。
  6. 让 root->lchild = p,表示 p 成为根结点的左孩子。
  7. 动态申请的结点用完后需释放;此示例先释放子结点,再释放根结点。

16.3.3 三叉链表

定义:#三叉链表

描述: 三叉链表在二叉链表的基础上,除了左孩子指针和右孩子指针外,还增加一个指向父结点的指针。

结构

  • 数据域。
  • 左孩子指针。
  • 右孩子指针。
  • 父结点指针。

目的

  • 方便从某个结点直接找到父结点。
  • 不需要从根结点重新遍历查找双亲。

考试注意

  • PDF 强调:考研中更喜欢考不带 parent 的方式。
  • 因此二叉链表是基础,三叉链表作为补充理解即可。

三叉链表代码

// 二叉树的结点(链式存储)
typedef struct BiTNode {
    ElemType data;                    // 数据域
    struct BiTNode *lchild, *rchild;   // 左、右孩子指针
    struct BiTNode *parent;            // 父结点指针
} BiTNode, *BiTree;

16.4 题型:二叉树性质计算

题型一:由 $n_0,n_1,n_2$ 求未知量

第一部分:解题方法

  1. 先写总数公式: $$ n=n_0+n_1+n_2 $$

  2. 再写二叉树核心公式: $$ n_0=n_2+1 $$

  3. 若题目给总边数或总结点数,再用: $$ \text{边数}=n-1 $$

  4. 若题目出现空指针数,再用: $$ \text{空指针数}=n+1 $$

第二部分:典型例题

例 1 一棵非空二叉树中,度为 $2$ 的结点有 $8$ 个,求叶子结点个数。

解析 $$ n_0=n_2+1=8+1=9 $$

答案 $$ 9 $$

例 2 一棵二叉树有 $20$ 个结点,求它的二叉链表空指针数。

解析 $$ \text{空指针数}=n+1=20+1=21 $$

答案 $$ 21 $$

第三部分:知识点复盘

  • 二叉树最常考公式是 $n_0=n_2+1$。
  • 空指针数不要写成 $2n$,$2n$ 是总指针域数。
  • 真实指向结点的指针数是 $n-1$。

题型二:完全二叉树编号计算

第一部分:解题方法

对完全二叉树按层序从 $1$ 开始编号:

  • 求左孩子,看 $2i$。
  • 求右孩子,看 $2i+1$。
  • 求父结点,看 $\left\lfloor i/2\right\rfloor$。
  • 求是否为叶子,看 $i>\left\lfloor n/2\right\rfloor$。
  • 求结点层次,看 $\left\lfloor\log_2 i\right\rfloor+1$。
  • 求整棵树高度,看 $\left\lceil\log_2(n+1)\right\rceil$ 或 $\left\lfloor\log_2 n\right\rfloor+1$。

第二部分:典型例题

例 1 一棵完全二叉树有 $100$ 个结点,编号为 $23$ 的结点,其父结点、左孩子、右孩子编号分别是多少?

解析 父结点: $$ \left\lfloor\frac{23}{2}\right\rfloor=11 $$

左孩子: $$ 2\times 23=46\le 100 $$

右孩子: $$ 2\times 23+1=47\le 100 $$

答案

  • 父结点编号为 $11$。
  • 左孩子编号为 $46$。
  • 右孩子编号为 $47$。

例 2 一棵完全二叉树有 $100$ 个结点,编号大于多少的结点一定是叶子结点?

解析 分支结点满足: $$ i\le \left\lfloor\frac{100}{2}\right\rfloor=50 $$

叶子结点满足: $$ i>50 $$

答案

  • 编号 $51\sim 100$ 的结点都是叶子结点。

第三部分:知识点复盘

  • 完全二叉树编号题默认从 $1$ 开始编号。
  • 若数组从 t[0] 开始连续存储,公式会发生变化;408 通常按编号从 $1$ 开始考。
  • 判断是否有孩子必须先和 $n$ 比较,不能只算出 $2i$ 或 $2i+1$。

题型三:完全二叉树中 $n_0,n_1,n_2$ 的数量

第一部分:解题方法

  1. 看总结点数 $n$ 的奇偶。
  2. 若 $n=2k$,则: $$ n_1=1,\quad n_0=k,\quad n_2=k-1 $$
  3. 若 $n=2k-1$,则: $$ n_1=0,\quad n_0=k,\quad n_2=k-1 $$

第二部分:典型例题

例 1 一棵完全二叉树有 $64$ 个结点,求 $n_0,n_1,n_2$。

解析 $$ 64=2k $$ $$ k=32 $$

所以: $$ n_1=1 $$ $$ n_0=32 $$ $$ n_2=31 $$

答案 $$ n_0=32,\quad n_1=1,\quad n_2=31 $$

例 2 一棵完全二叉树有 $63$ 个结点,求 $n_0,n_1,n_2$。

解析 $$ 63=2k-1 $$ $$ k=32 $$

所以: $$ n_1=0 $$ $$ n_0=32 $$ $$ n_2=31 $$

答案 $$ n_0=32,\quad n_1=0,\quad n_2=31 $$

第三部分:知识点复盘

  • 完全二叉树最多只有一个度为 $1$ 的结点。
  • 总结点数为偶数时,存在一个度为 $1$ 的结点。
  • 总结点数为奇数时,不存在度为 $1$ 的结点。

相关知识

16.5 本节复盘

必须背熟的公式

公式 含义
$n=n_0+n_1+n_2$ 二叉树按结点度分类
$n=n_1+2n_2+1$ 结点数等于总度数加 $1$
$n_0=n_2+1$ 叶子结点比分支度为 $2$ 的结点多 $1$
第 $k$ 层最多 $2^{k-1}$ 个结点 层数从 $1$ 开始
高度为 $h$ 最多 $2^h-1$ 个结点 满二叉树达到最大
空指针数 $n+1$ 二叉链表空链域数量
完全二叉树高度 $\left\lceil\log_2(n+1)\right\rceil$ 由总结点数求高度
完全二叉树高度 $\left\lfloor\log_2 n\right\rfloor+1$ 与上一公式等价
结点 $i$ 的层次 $\left\lfloor\log_2 i\right\rfloor+1$ 由编号求层次

完全二叉树编号规则

目标 条件或公式
父结点 $\left\lfloor i/2\right\rfloor$,其中 $i>1$
左孩子 $2i$,且 $2i\le n$
右孩子 $2i+1$,且 $2i+1\le n$
分支结点 $i\le \left\lfloor n/2\right\rfloor$
叶子结点 $i> \left\lfloor n/2\right\rfloor$

易错点

  • 二叉树可以为空,空二叉树不是“不存在”。
  • 二叉树的左右子树不能颠倒。
  • 满二叉树一定是完全二叉树;完全二叉树不一定是满二叉树。
  • 度为 $2$ 的有序树不等于二叉树。
  • 顺序存储天然适合完全二叉树;其他二叉树也能补空位存储,但可能严重浪费空间。
  • 非完全二叉树顺序存储时需要补空位置,并用 isEmpty 判断。
  • 三叉链表有 parent 指针,但 408 更常考二叉链表。