二叉树的度是什么
二叉树 (binary tree)是一种非线性数据结构,代表着祖先与后代之间的派生关系,体现着“一分为二”的分治逻辑。与链表类似,二叉树的基本单元是节点,每个节点包含:值、左子节点引用、右子节点引用。
/* 二叉树节点类 */
class TreeNode {
val; // 节点值
left; // 左子节点指针
right; // 右子节点指针
constructor(val, left, right) {
this.val = val === undefined ? 0 : val;
this.left = left === undefined ? null : left;
this.right = right === undefined ? null : right;
}
}
每个节点都有两个引用(指针),分别指向左子节点 (left-child node)和右子节点 (right-child node),该节点被称为这两个子节点的父节点 (parent node)。当给定一个二叉树的节点时,我们将该节点的左子节点及其以下节点形成的树称为该节点的左子树 (left subtree),同理可得右子树 (right subtree)。
在二叉树中,除叶节点外,其他所有节点都包含子节点和非空子树。如下图1所示,如果将“节点 2”视为父节点,则其左子节点和右子节点分别是“节点 4”和“节点 5”,左子树是“节点 4 及其以下节点形成的树”,右子树是“节点 5 及其以下节点形成的树”。

图1 父节点、子节点、子树
01 二叉树常见术语
二叉树的常用术语如下图2所示。
- 根节点 (root node):位于二叉树顶层的节点,没有父节点。
- 叶节点 (leaf node):没有子节点的节点,其两个指针均指向 \(\text{None}\) 。
- 边 (edge):连接两个节点的线段,即节点引用(指针)。
- 节点所在的层 (level):从顶至底递增,根节点所在层为 1 。
- 节点的度 (degree):节点的子节点的数量。在二叉树中,度的取值范围是 0、1、2 。
- 二叉树的高度 (height):从根节点到最远叶节点所经过的边的数量。
- 节点的深度 (depth):从根节点到该节点所经过的边的数量。
- 节点的高度 (height):从距离该节点最远的叶节点到该节点所经过的边的数量。

图2 二叉树的常见术语
02 二叉树的基本操作
1.初始化二叉树
与链表类似,首先初始化节点,然后构建引用(指针)。
/* 初始化二叉树 */
// 初始化节点
let n1 = new TreeNode(1),
n2 = new TreeNode(2),
n3 = new TreeNode(3),
n4 = new TreeNode(4),
n5 = new TreeNode(5);
// 构建引用指向(即指针)
n1.left = n2;
n1.right = n3;
n2.left = n4;
n2.right = n5;
2.插入与删除节点
与链表类似,在二叉树中插入与删除节点可以通过修改指针来实现。图3给出了一个示例。

图3 在二叉树中插入与删除节点
/* 插入与删除节点 */
let P = new TreeNode(0);
// 在 n1 -> n2 中间插入节点 P
n1.left = P;
P.left = n2;
// 删除节点 P
n1.left = n2;
3. 常见二叉树的类型
3.1 完美二叉树
完美二叉树 (perfect binary tree)所有层的节点都被完全填满。在完美二叉树中,叶节点的度为 0 ,其余所有节点的度都为 2 ;若树高度为 h ,则节点总数为 2^{h+1} - 1 ,呈现标准的指数级关系,反映了自然界中常见的细胞分裂现象。

图4 完美二叉树
3.2 完全二叉树
如下图5所示,完全二叉树 (complete binary tree)只有最底层的节点未被填满,且最底层节点尽量靠左填充。

图5 完全二叉树
3.3 完满二叉树
如下图6所示,完满二叉树 (full binary tree)除了叶节点之外,其余所有节点都有两个子节点。

图6 完满二叉树
3.4 平衡二叉树
如下图7所示,平衡二叉树 (balanced binary tree)中任意节点的左子树和右子树的高度之差的绝对值不超过 1 。

图7 平衡二叉树
3.5 二叉树退化
下图8展示了二叉树的理想与退化状态。当二叉树的每层节点都被填满时,达到“完美二叉树”;而当所有节点都偏向一侧时,二叉树退化为“链表”。
- 完美二叉树是理想情况,可以充分发挥二叉树“分治”的优势。
- 链表则是另一个极端,各项操作都变为线性操作,时间复杂度退化至 O(n) 。

图8 二叉树的最佳与最差结构