树的概念和性质

news2024/7/4 6:09:41

文章目录

  • 树的基本概念
    • 树的定义和术语
    • 树的遍历
    • 树的种类
  • 二叉树
    • 二叉搜索树
      • AVL 树
      • 红黑树
    • 完全二叉树和满二叉树
    • 哈夫曼树
  • 多叉树
  • B 树及其变种
    • B 树
    • B+ 树和 B* 树
  • 目录

树的基本概念

树的定义和术语

树是由零个或多个结点组成的具有层级关系的数据结构。

当树的结点数量等于零时,称为空树。当树的结点数量大于零时,定义以下术语:根结点、叶结点、父结点、子结点、子树。

  • 树中有一个唯一的根结点。
  • 每个结点有零个或多个子结点,没有子结点的结点称为叶结点。
  • 根结点没有父结点,除了根结点以外的每个结点有且只有一个父结点。
  • 父结点和子结点是相对关系,甲结点是乙结点的父结点等价于乙结点是甲结点的子结点。
  • 对于父结点而言,以子结点为根结点的树称为父结点的子树。

根据父结点和子结点的定义,还可以定义兄弟结点、堂兄弟结点、祖先和后代。

  • 如果两个结点的父结点相同,则这两个结点为兄弟结点。
  • 如果两个结点的父结点不同且位于同一层,则这两个结点为堂兄弟结点。
  • 如果以结点甲为根的子树中存在结点乙,则结点甲是结点乙的祖先,结点乙是结点甲的后代。

由于树中的结点之间存在层级关系,因此还需要定义树中的边、结点的层级以及树的层级和树的高度。层级和高度的定义取决于具体场景。

  • 当且仅当两个结点之间的关系是父结点和子结点的关系时,两个结点之间有一条边相连。
  • 根结点所在层定义为第 0 0 0 层或第 1 1 1 层。如果两个结点之间的关系是父结点和子结点的关系,则子结点的层数为父结点的层数加 1 1 1
  • 树的层级定义为树中结点所在的不同层级的数量,为最远叶结点的层数和根结点的层数之差加 1 1 1
  • 树的高度可以定义为:树的层级;从根结点到最远叶结点的路径上的边数;从根结点到最远叶结点的路径上的结点数。

由于树中的每一条边一定连接父结点和子结点,因此树中不存在环。在树中任选两个结点,这两个结点之间的路径一定是唯一的。

树的遍历

树的遍历指的是按照特定顺序依次访问树中的每个结点,使得每个结点恰好被访问一次。树的遍历可以分成两大类,基于深度优先搜索的遍历和基于广度优先搜索的遍历。

深度优先搜索的方法为:从根结点开始,对于每个可能的分支路径深入搜索下一个结点,遇到叶结点时,回退到上一个结点并对其余的分支路径继续搜索,直到遍历完所有可能的分支路径。深度优先搜索基于栈实现,可以通过递归的方式或者显性使用栈的方式实现。

广度优先搜索的方法为:从根结点开始,依次遍历每一层的结点,直到遍历完最后一层的结点。广度优先搜索基于队列实现。

二叉树和多叉树部分将会具体介绍树的遍历方法。

树的种类

树的种类有很多,以下列举常见的树。

  • 二叉树:最常见的树结构,树中的每个结点最多有两个子结点,两个结点分别为左子结点和右子结点。特殊的二叉树包括二叉搜索树、完全二叉树、满二叉树、哈夫曼树等。
  • 多叉树:最一般化的树结构,树中的每个结点可以有任意个子结点。
  • B 树:多叉树的一种,也称平衡多路搜索树,适用于磁盘和其他存储设备。B 树的两个常见的变种是 B+ 树和 B* 树。
  • 字典树:也称前缀树,为多叉树的一种,可以用于字符串的检索,其使用空间小于哈希表。字典树将在高级数据结构部分具体讲解。

二叉树

二叉树是最常见的树结构。二叉树中的每个结点最多有两个子结点,且子结点有左右之分。

在 LeetCode 中定义了类 TreeNode \texttt{TreeNode} TreeNode,该类定义了二叉树的一个结点。 TreeNode \texttt{TreeNode} TreeNode 类的 Java 代码定义如下:

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode() {}
    TreeNode(int val) { this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

二叉树的遍历有四种:前序遍历、中序遍历、后序遍历和层序遍历。其中,前序遍历、中序遍历和后序遍历基于深度优先搜索,层序遍历基于广度优先搜索。

  • 前序遍历的方法为:依次遍历根结点、左子树和右子树,对于左子树和右子树使用同样的方法遍历。
  • 中序遍历的方法为:依次遍历左子树、根结点和右子树,对于左子树和右子树使用同样的方法遍历。
  • 后序遍历的方法为:依次遍历左子树、右子树和根结点,对于左子树和右子树使用同样的方法遍历。
  • 层序遍历的方法为:从根结点开始,依次遍历每一层的结点。

前序遍历、中序遍历和后序遍历可以使用递归和迭代的方式实现,时间复杂度是 O ( n ) O(n) O(n),空间复杂度是 O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数,也可以使用莫里斯遍历实现,时间复杂度是 O ( n ) O(n) O(n),空间复杂度是 O ( 1 ) O(1) O(1)

下图为一个二叉树,共有 10 10 10 个结点。

图 1

图中的二叉树的四种遍历的结果如下。

  • 前序遍历: [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] [1,2,3,4,5,6,7,8,9,10] [1,2,3,4,5,6,7,8,9,10]
  • 中序遍历: [ 4 , 3 , 2 , 5 , 6 , 1 , 7 , 9 , 8 , 10 ] [4,3,2,5,6,1,7,9,8,10] [4,3,2,5,6,1,7,9,8,10]
  • 后序遍历: [ 4 , 3 , 6 , 5 , 2 , 9 , 10 , 8 , 7 , 1 ] [4,3,6,5,2,9,10,8,7,1] [4,3,6,5,2,9,10,8,7,1]
  • 层序遍历: [ 1 , 2 , 7 , 3 , 5 , 8 , 4 , 6 , 9 , 10 ] [1,2,7,3,5,8,4,6,9,10] [1,2,7,3,5,8,4,6,9,10]

如果知道二叉树的前序遍历和中序遍历的结果,或者知道二叉树的中序遍历和后序遍历的结果,则可以唯一地确定二叉树。如果只知道二叉树的前序遍历和后序遍历的结果,则一般不能唯一地确定二叉树。

二叉搜索树

二叉搜索树是特殊的二叉树,结点值之间满足特定的顺序。二叉搜索树具有以下性质。

  • 空二叉树(即不含任何结点的二叉树)是二叉搜索树。
  • 根结点的左子树中的每一个结点的值都小于根结点的值。
  • 根结点的右子树中的每一个结点的值都大于根结点的值。
  • 根结点的左子树和右子树也是二叉搜索树。

下图为一个二叉搜索树。

图 2

根据二叉搜索树的性质可知,二叉搜索树的中序遍历序列中,结点值的顺序一定是递增的,因此可以根据二叉树的中序遍历序列判断二叉树是不是二叉搜索树。

利用二叉搜索树的性质,在二叉搜索树中搜索特定目标值不需要遍历全部结点,而是每次只需要在一个子树中查找,因此可以排除另一个子树中的结点。在二叉搜索树中搜索特定目标值的操作如下:从根结点开始,如果当前结点的值大于目标值则在左子树中继续搜索,如果当前结点的值小于目标值则在右子树中继续搜索,直到找到目标值,如果搜索到叶结点仍未找到目标值则目标值不存在。二叉搜索树的插入操作和删除操作都基于搜索操作,且在插入操作和删除操作之后仍然满足二叉搜索树的性质。

假设二叉搜索树的结点数是 n n n,二叉搜索树的搜索、插入和删除操作的平均时间复杂度是 O ( log ⁡ n ) O(\log n) O(logn)。最坏情况下,二叉搜索树中的每个结点都只有一个子结点,此时二叉搜索树的搜索、插入和删除操作的时间复杂度退化为线性的 O ( n ) O(n) O(n)。为了避免出现二叉搜索树操作的时间复杂度过高,应将二叉搜索树维护成平衡二叉搜索树。两种常见的平衡二叉搜索树是 AVL 树和红黑树,都满足各项操作的平均时间复杂度是 O ( log ⁡ n ) O(\log n) O(logn)

AVL 树

AVL 树是平衡二叉搜索树,由两名前苏联的科学家 G. M. Adelson-Velsky 和 E. M. Landis 提出,根据两名科学家的名字命名。AVL 树具有以下性质。

  • 空二叉搜索树是 AVL 树。
  • 根结点的左子树和右子树的高度之差的绝对值不超过 1 1 1
  • 根结点的左子树和右子树也是 AVL 树。

下图为一个 AVL 树。

图 3

AVL 树中的每个结点都有一个平衡因子,一个结点的平衡因子定义为该结点的左子树和右子树的高度之差,AVL 树满足每个结点的平衡因子的绝对值都不超过 1 1 1。在插入和删除操作时,需要通过旋转操作维护 AVL 树的平衡性。

红黑树

红黑树是近似平衡的二叉搜索树,具有以下性质。

  • 每个结点是黑色或红色。
  • 根结点是黑色。
  • 所有的叶结点都是黑色,红黑树中的叶结点为空结点。
  • 每个红色结点的子结点都是黑色。
  • 从任意一个结点出发,到其子树中的每个叶结点的所有路径都包含相同数目的黑色结点。

下图为一个红黑树。

图 4

在插入和删除操作时,需要通过旋转和着色操作维护红黑树的性质。

由于红黑树中没有平衡因子,因此红黑树不像 AVL 树严格平衡,但是和 AVL 树相比,维护红黑树性质的代价较低,因此在各项操作的平均性能方面,红黑树优于 AVL 树。

完全二叉树和满二叉树

完全二叉树的定义是:如果二叉树除了最深一层以外,其余每一层的结点个数都达到最大值,且最深一层的结点在最左边的连续位置,则这样的二叉树是完全二叉树。假设完全二叉树有 l l l 层和 n n n 个结点,且根结点位于第 0 0 0 层,则完全二叉树具有以下性质。

  • 对于 0 ≤ i < n − 1 0 \le i < n - 1 0i<n1,第 i i i 层有 2 i 2^i 2i 个结点。
  • 最深一层为第 n − 1 n - 1 n1 层,最深一层的结点数范围是 [ 1 , 2 n − 1 ] [1, 2^{n - 1}] [1,2n1]
  • 层数 l l l 和结点数 n n n 之间的关系为: l = ⌊ log ⁡ 2 n ⌋ + 1 l = \lfloor \log_2 n \rfloor + 1 l=log2n+1

下图为一个完全二叉树。

图 5

满二叉树的定义是:如果二叉树的每一层的结点个数都达到最大值,则这样的二叉树是满二叉树。根据定义可知,满二叉树是特殊的完全二叉树。假设满二叉树有 l l l 层和 n n n 个结点,且根结点位于第 0 0 0 层,则满二叉树具有以下性质。

  • 对于 0 ≤ i < n 0 \le i < n 0i<n,第 i i i 层有 2 i 2^i 2i 个结点。
  • 层数 l l l 和结点数 n n n 之间的关系为: l = log ⁡ 2 ( n + 1 ) l = \log_2 (n + 1) l=log2(n+1) n = 2 l − 1 n = 2^l - 1 n=2l1

下图为一个满二叉树。

图 6

哈夫曼树

在介绍哈夫曼树之前,首先需要介绍带权值二叉树。带权值的二叉树中,每个结点都有一个权值,一个结点的带权路径长度为从根结点到该结点的路径长度(路径包含的边数,或者路径上的结点数减 1 1 1)与该结点的权值的乘积。

如果一个带权值二叉树满足所有叶结点的带权路径长度之和最小,则称为哈夫曼树或最优二叉树。哈夫曼树的特点是权值大的结点离根结点近,权值小的结点离根结点远。

哈夫曼树的常见应用是文件压缩,将每个字符转成二进制表示,从而达到减少压缩文件空间的目的。为了能在压缩文件之后解压缩得到原始文件,必须使用无损压缩,因此必须满足以下两点要求。

  • 压缩文件中必须存储哈夫曼树,哈夫曼树是解压缩文件恢复原始字符的依据。
  • 根据二进制表示解压缩得到的结果必须是唯一的,不能存在歧义,因此任何一个字符的二进制表示都不能是另一个字符的二进制表示的前缀。

使用哈夫曼树实现文件的压缩和解压缩的做法如下。

  1. 统计文件中每个字符的出现频率。
  2. 将每个字符的出现频率作为权值,构建哈夫曼树,得到每个字符对应的二进制表示,称为哈夫曼编码。
  3. 在压缩文件中存储生成的哈夫曼树,然后将每个字符对应的哈夫曼编码依次写入压缩文件中。
  4. 解压缩文件时,首先从压缩后的文件中取出哈夫曼树,然后遍历压缩文件中的二进制表示,根据哈夫曼树恢复原文件的每个字符。

哈夫曼树的构建方法为自底向上。初始时,每个字符对应一个结点,结点的权值为字符的出现频率。每次选两个权值最低的结点,创建新结点,新结点的两个子结点为两个权值最低的结点,新结点的权值为两个权值最低的结点之和,用新结点代替两个权值最低的结点。重复该过程,直到最后剩下一个结点,该结点是哈夫曼树的根结点,此时哈夫曼树构造完成。

以下用一个例子说明哈夫曼树的构建。

假设一个文件中有 5 5 5 种不同的字符,其中字符 a \text{a} a 出现 11 11 11 次,字符 b \text{b} b 出现 13 13 13 次,字符 c \text{c} c 出现 22 22 22 次,字符 d \text{d} d 出现 23 23 23 次,字符 e \text{e} e 出现 31 31 31 次。

  1. 初始时有 5 5 5 个结点:结点 a \text{a} a 的权值是 11 11 11,结点 b \text{b} b 的权值是 13 13 13,结点 c \text{c} c 的权值是 22 22 22,结点 d \text{d} d 的权值是 23 23 23,结点 e \text{e} e 的权值是 31 31 31
  2. 权值最低的两个结点是 a \text{a} a b \text{b} b,根据这两个结点创建新结点 ab \text{ab} ab,新结点的权值是 11 + 13 = 24 11 + 13 = 24 11+13=24。此时有 4 4 4 个结点:结点 c \text{c} c 的权值是 22 22 22,结点 d \text{d} d 的权值是 23 23 23,结点 ab \text{ab} ab 的权值是 24 24 24,结点 e \text{e} e 的权值是 31 31 31
  3. 权值最低的两个结点是 c \text{c} c d \text{d} d,根据这两个结点创建新结点 cd \text{cd} cd,新结点的权值是 22 + 23 = 45 22 + 23 = 45 22+23=45。此时有 3 3 3 个结点:结点 ab \text{ab} ab 的权值是 24 24 24,结点 e \text{e} e 的权值是 31 31 31,结点 cd \text{cd} cd 的权值是 45 45 45
  4. 权值最低的两个结点是 ab \text{ab} ab e \text{e} e,根据这两个结点创建新结点 abe \text{abe} abe,新结点的权值是 24 + 31 = 55 24 + 31 = 55 24+31=55。此时有 2 2 2 个结点:结点 cd \text{cd} cd 的权值是 45 45 45,结点 abe \text{abe} abe 的权值是 55 55 55
  5. 剩下两个结点 cd \text{cd} cd abe \text{abe} abe,根据这两个结点创建新结点 abcde \text{abcde} abcde,新结点的权值是 45 + 55 = 100 45 + 55 = 100 45+55=100。此时有 1 1 1 个结点:结点 abcde \text{abcde} abcde 的权值是 100 100 100。由于只剩 1 1 1 个结点,该结点是哈夫曼树的根结点,此时哈夫曼树构造完成。

下图为根据上述例子构建的哈夫曼树。

图 7

根据构建的哈夫曼树,可以得到每个字符对应的哈夫曼编码: a = 100 \text{a} = 100 a=100 b = 101 \text{b} = 101 b=101 c = 00 \text{c} = 00 c=00 d = 01 \text{d} = 01 d=01 e = 11 \text{e} = 11 e=11。其中, a \text{a} a b \text{b} b 对应的哈夫曼编码的长度是 3 3 3 c \text{c} c d \text{d} d e \text{e} e 对应的哈夫曼编码的长度是 2 2 2,满足权值大的结点离根结点近,权值小的结点离根结点远。

多叉树

多叉树是最一般化的树结构。多叉树中的每个结点可以有任意个子结点,同一个结点的子结点之间可能有顺序关系也可能没有顺序关系,子结点之间有顺序关系的多叉树称为有序树,子结点之间没有顺序关系的多叉树称为无序树或自由树。

在 LeetCode 中定义了类 Node \texttt{Node} Node,该类定义了多叉树的一个结点。 Node \texttt{Node} Node 类的 Java 代码定义如下:

class Node {
    public int val;
    public List<Node> children;

    public Node() {}

    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, List<Node> _children) {
        val = _val;
        children = _children;
    }
}

多叉树的遍历有三种:前序遍历、后序遍历和层序遍历。其中,前序遍历和后序遍历基于深度优先搜索,层序遍历基于广度优先搜索。

  • 前序遍历的方法为:首先遍历根结点,然后依次遍历根结点的每一个子树,对于每一个子树使用同样的方法遍历。
  • 后序遍历的方法为:依次遍历根结点的每一个子树,最后遍历根结点,对于每一个子树使用同样的方法遍历。
  • 层序遍历的方法为:从根结点开始,依次遍历每一层的结点。

前序遍历和后序遍历可以使用递归和迭代的方式实现。

下图为一个多叉树,共有 10 10 10 个结点。

图 8

图中的多叉树的三种遍历的结果如下。

  • 前序遍历: [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] [1,2,3,4,5,6,7,8,9,10] [1,2,3,4,5,6,7,8,9,10]
  • 后序遍历: [ 2 , 4 , 3 , 6 , 7 , 5 , 9 , 10 , 8 , 1 ] [2,4,3,6,7,5,9,10,8,1] [2,4,3,6,7,5,9,10,8,1]
  • 层序遍历: [ 1 , 2 , 3 , 5 , 8 , 4 , 6 , 7 , 9 , 10 ] [1,2,3,5,8,4,6,7,9,10] [1,2,3,5,8,4,6,7,9,10]

B 树及其变种

B 树

B 树也称平衡多路搜索树。B 树和二叉搜索树的不同之处在于,B 树的每个结点可以有多个关键字和多个子结点。

B 树需要定义阶数,阶数至少为 2 2 2,一个 m m m 阶的 B 树具有以下性质。

  • 同一个结点中的关键字按照递增顺序排列。
  • 每个结点至多有 m − 1 m - 1 m1 个关键字,每个非根结点至少有 ⌈ m 2 ⌉ − 1 \Big\lceil \dfrac{m}{2} \Big\rceil - 1 2m1 个关键字,根结点至少有 1 1 1 个关键字。
  • 每个结点至多有 m m m 个子结点,每个非根且非叶结点至少有 ⌈ m 2 ⌉ \Big\lceil \dfrac{m}{2} \Big\rceil 2m 个子结点,根结点如果不是叶结点则至少有 2 2 2 个子结点。
  • 所有叶结点位于同一层。
  • 每个关键字的两侧各有一条边指向子结点,左侧的边指向的子结点中的关键字都小于当前关键字,右侧的边指向的子结点中的关键字都大于当前关键字。

下图为一个 B 树,阶数为 4 4 4,共有 9 9 9 个结点, 20 20 20 个关键字。

图 9

在插入和删除操作时,需要通过拆分结点与合并结点操作维护 B 树的阶数性质。

B+ 树和 B* 树

B+ 树是 B 树的变种。B 树和 B+ 树有以下区别。

  • B+ 树中每个结点的关键字个数和该结点的子结点个数相同。
  • 所有的非叶结点存放索引信息。
  • 所有的叶结点存放全部关键字。
  • 所有的叶结点之间形成单向链表。

B* 树是 B+ 树的变种。B+ 树和 B* 树有以下区别。

  • 不同于 B+ 树只有叶结点之间形成单向链表,B* 树的每一层结点分别形成单向链表。
  • B+ 树的最低利用率是 1 2 \dfrac{1}{2} 21,B* 树的最低利用率是 2 3 \dfrac{2}{3} 32

目录

  1. 二叉树题目:二叉树的前序遍历
  2. 二叉树题目:二叉树的中序遍历
  3. 二叉树题目:二叉树的后序遍历
  4. 二叉树题目:二叉树展开为链表
  5. 二叉树题目:单值二叉树
  6. 二叉树题目:相同的树
  7. 二叉树题目:对称二叉树
  8. 二叉树题目:翻转二叉树
  9. 二叉树题目:合并二叉树
  10. 二叉树题目:二叉树的最大深度
  11. 二叉树题目:二叉树的最小深度
  12. 二叉树题目:路径总和
  13. 二叉树题目:从根到叶的二进制数之和
  14. 二叉树题目:左叶子之和
  15. 二叉树题目:叶子相似的树
  16. 二叉树题目:二叉树的堂兄弟结点
  17. 二叉树题目:根据二叉树创建字符串
  18. 二叉树题目:二叉树的直径
  19. 二叉树题目:二叉树的坡度
  20. 二叉树题目:二叉树的层序遍历
  21. 二叉树题目:二叉树的层序遍历 II
  22. 二叉树题目:二叉树的锯齿形层序遍历
  23. 二叉树题目:二叉树的右视图
  24. 二叉树题目:填充每个结点的下一个右侧结点指针
  25. 二叉树题目:填充每个结点的下一个右侧结点指针 II
  26. 二叉树题目:二叉树的层平均值
  27. 二叉树题目:最大层内元素和
  28. 二叉树题目:层数最深叶子结点的和
  29. 二叉树题目:奇偶树
  30. 二叉树题目:翻转等价二叉树
  31. 二叉树题目:二叉树剪枝
  32. 二叉树题目:平衡二叉树
  33. 二叉树题目:路径总和 II
  34. 二叉树题目:二叉树的所有路径
  35. 二叉树题目:二叉树寻路
  36. 二叉树题目:从前序与中序遍历序列构造二叉树
  37. 二叉树题目:从中序与后序遍历序列构造二叉树
  38. 二叉树题目:最大二叉树
  39. 二叉树题目:最大二叉树 II
  40. 二叉树题目:路径总和 III
  41. 二叉树题目:在二叉树中增加一行
  42. 二叉树题目:二叉树最大宽度
  43. 二叉树题目:统计二叉树中好结点的数目
  44. 二叉树题目:二叉树的最近公共祖先
  45. 二叉树题目:具有所有最深结点的最小子树
  46. 二叉树题目:结点与其祖先之间的最大差值
  47. 二叉树题目:祖父结点值为偶数的结点和
  48. 二叉树题目:二叉树的完全性检验
  49. 二叉树题目:翻转二叉树以匹配前序遍历
  50. 二叉树题目:在受污染的二叉树中查找元素
  51. 二叉树题目:从前序遍历还原二叉树
  52. 二叉树题目:二叉树着色游戏
  53. 二叉树题目:输出二叉树
  54. 二叉树题目:分裂二叉树的最大乘积
  55. 二叉树题目:在二叉树中分配硬币
  56. 二叉树题目:根到叶路径上的不足结点
  57. 二叉树题目:删点成林
  58. 二叉树题目:好叶子结点对的数量
  59. 二叉树题目:完全二叉树插入器
  60. 二叉树题目:从前序与后序遍历序列构造二叉树
  61. 二叉树题目:寻找重复的子树
  62. 二叉树题目:二叉树的序列化与反序列化
  63. 二叉搜索树操作题目:二叉搜索树中的搜索操作
  64. 二叉搜索树操作题目:二叉搜索树中的插入操作
  65. 二叉搜索树操作题目:删除二叉搜索树中的结点
  66. 二叉搜索树题目:二叉搜索树的最近公共祖先
  67. 二叉搜索树题目:验证二叉搜索树
  68. 二叉搜索树题目:二叉搜索树的最小绝对差
  69. 二叉搜索树题目:递增顺序搜索树
  70. 二叉搜索树题目:修剪二叉搜索树
  71. 二叉搜索树题目:二叉搜索树的范围和
  72. 二叉搜索树题目:二叉搜索树中的众数
  73. 二叉搜索树题目:把二叉搜索树转换为累加树
  74. 二叉搜索树题目:将有序数组转换为二叉搜索树
  75. 二叉搜索树题目:二叉搜索树迭代器
  76. 二叉搜索树题目:前序遍历构造二叉搜索树
  77. 二叉搜索树题目:恢复二叉搜索树
  78. 二叉搜索树题目:将有序链表转换为二叉搜索树
  79. 二叉搜索树题目:序列化和反序列化二叉搜索树
  80. 多叉树题目:N 叉树的前序遍历
  81. 多叉树题目:N 叉树的后序遍历
  82. 多叉树题目:N 叉树的最大深度
  83. 多叉树题目:N 叉树的层序遍历
  84. 多叉树题目:子树中标签相同的结点数
  85. 多叉树题目:王位继承顺序
  86. 多叉树题目:收集树上所有苹果的最少时间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/638674.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

暴力递归到动态规划(四)

⭐️前言⭐️ 本篇文章是从暴力递归到动态规划篇目的最后一篇文章&#xff0c;包含了几道题目还有最终的大总结&#xff0c;相信这篇文章能让各位读者对动态规划有更深一步的了解。 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601…

使用大型语言模(LLM)构建系统(五):输出结果检查

今天我学习了DeepLearning.AI的 Building Systems with LLM 的在线课程&#xff0c;我想和大家一起分享一下该门课程的一些主要内容。今天我们来学习输出结果检查。输出结果检查包含以下两部分内容&#xff1a; 检查输出是否存在潜在有害内容检查输出是否基于提供的产品信息 下…

easyrecovery2023永久免费版激活密钥,手把手教您用EasyRecovery快速恢复数据

Ontrack EasyRecovery Crack Professional是一个全面的备份和恢复实用程序&#xff0c;可以从多个数据丢失事件中恢复文件&#xff0c;例如常见的意外删除、更严重的&#xff08;有时是病毒引起的&#xff09;分区或驱动器格式化&#xff0c;甚至硬盘严重损坏后的数据丢失。免费…

Python实现ACO蚁群优化算法优化LightGBM回归模型(LGBMRegressor算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 蚁群优化算法(Ant Colony Optimization, ACO)是一种源于大自然生物世界的新的仿生进化算法&#xff0c…

全球计算科学和人工智能领域Altair

作为全球计算科学和人工智能领域的领导者 Altair,全新数据分析与人工智能平台 Altair RapidMiner。此次启动仪式以 “数据科学&#xff0c;解码智能未来” 为主题。目的是为了更好的助力本土用户推进高效数字化转型&#xff0c;实现数据分析与人工智能应用的降本增效. 作为全球…

PR视频导出时出现编译影片出错的提示怎么解决?

大家使用PR软件的时候因为版本不兼容等各种原因&#xff0c;导致剪辑好的视频导不出来&#xff08;如下图所示&#xff09;&#xff0c;这种情况有两种方法可以解决。&#xff08;我用的版本是2022Pro&#xff0c;电脑需要Win10的系统&#xff0c;如有需要下载的&#xff0c;可…

使用 Terraform 在 GCP 上一键部署 EMQX MQTT Broker

引言 MQTT 是一种轻量级的消息传递协议&#xff0c;适用于物联网应用实现设备间通信。 作为一款主流的开源 MQTT Broker&#xff0c;EMQX 能够提供高扩展性、可靠性和安全性的 MQTT 消息传递服务。 借助广泛应用的基础设施即代码&#xff08;IaC&#xff09;工具 Terraform&a…

外包干了4年,人直接废了···

有一说一&#xff0c;外包没有给很高的薪资&#xff0c;是真不能干呀&#xff01; 先说一下自己的情况&#xff0c;大专生&#xff0c;19年通过校招进入湖南某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0…

【javaScript】Proxy与Object.defineProperty的区别

目录 功能方面的区别&#xff1a;Object.defineProperty对整个对象进行赋值&#xff0c;不会触发set拦截Object.defineProperty对整个对象进行遍历&#xff0c;不会触发get拦截Proxy自定义拦截行为 Proxy的优缺点优点&#xff1a;缺点 Proxy和Object.defineProperty都是JavaScr…

亿发软件:中医药信息一体化解决方案,智慧中药房煎配系统

智慧中药房是中医药服务的一种新模式&#xff0c;随着中医药信息化建设逐渐兴起&#xff0c;湖南远跃顺应时代发展需求&#xff0c;深度分析中医药行业现状&#xff0c;充分发挥研发技术创新&#xff0c;融合运用互联网、物联网、大数据等技术创新成果&#xff0c;研发出中药信…

上市后首份年报,读书郎去年净利下滑94%

又是一年高考逐梦时&#xff0c;寒窗二十四年的读书郎如何克服“偏科”症&#xff1f; 近日&#xff0c;读书郎教育控股有限公司&#xff08;下称“读书郎”,02385.HK)交出了上市后的首份年报。 3月29日&#xff0c;财报公布的首个交易日&#xff0c;其股价下跌0.27%&#xf…

起点,而非终点——我的创作纪念日

机缘 我注定遇见CSDN. 作为一位oier,在学习算法,查找题解的时候&#xff0c;第一个看到的&#xff0c;总是CSDN。 于是&#xff0c;我加入了CSDN这个家庭。 茫茫然然&#xff0c;带着无限的憧憬&#xff0c;我写下了第一篇文章&#xff1a;《你好&#xff0c;CSDN》 我的C…

什么是融合CDN?融合CDN的优势和常见的调度模式有哪些?

什么是融合CDN&#xff1f; 为了理解什么是融合CDN&#xff0c;我们先了解什么是CDN。CDN是一个地理分布的边缘服务器网络&#xff0c;其目标是提供更快、可靠的互联网内容交付。CDN通过在网络边缘缓存互联网内容来实现这一点&#xff0c;从而减少数据源和最终用户之间的物理距…

“入职半年,绩效背了C”,谈谈「绩效管理」的误区及对策

职场打工人上班吃维C&#xff0c;绩效却背C&#xff0c;苦C久矣&#xff01; 又到年中“考核季”&#xff0c;被绩效考核折磨到“头秃”的职场打工人们&#xff0c;选择将情绪释放到社交平台。 一位朋友分享了自己绩效被打C的经历&#xff1a;“茶饭不思&#xff0c;感觉自己很…

数学建模经历-程序人生

引言 即将大四毕业(现在大三末)&#xff0c;闲来无事(为了冲粽子)就写一篇记录数学建模经历的博客吧。其实经常看到一些大佬的博客里会有什么"程序人生"、"人生感想"之类的专栏&#xff0c;但是由于我只是一个小趴菜没什么阅历因此也就没有写过类似的博客…

一文详解IPv4与IPv6协议

前段时间的工作大多与通信协议相关&#xff0c;随着协议相关工作的不断深入&#xff0c;相关数据包的分析占据了不少工作时间。在数据报文分析中&#xff0c;发现大学期间IP协议内容已经重新还给了老师&#xff0c;相关知识完全没有了印象&#xff0c;这篇文章算是一篇复习文&a…

Day05 04-MySQL分库分表介绍

文章目录 第十七章 MySQL分库分表17.1 什么是分库分表17.2 为什么要分库分表17.3 垂直切分17.3.1 垂直分库17.3.2 垂直分表 17.4 水平切分17.4.1 水平分库17.4.2 水平分表17.4.3 常见的水平切分规则 第十七章 MySQL分库分表 17.1 什么是分库分表 MySQL数据库常见的优化方案中…

新的管理中心应用

大家好&#xff0c;才是真的好。 Notes/Domino 14 Drop1如约而至&#xff0c;让我们有了很多内容要写。首先是管理新特性&#xff0c;就像上篇和大家介绍的&#xff0c;感受最直接的就是新的管理中心应用AdminCentral。 以目前的Drop1环境来看&#xff0c;管理中心应用主要功…

plus.runtime.version总是13.8.4

引言 最近在uniapp中使用到了plus.runtime.version&#xff0c;但是在开发环境下一直无法获取到真正的版本号&#xff0c;他的值一直都是13.8.4&#xff0c;在全局进行搜索也没有发现哪里设置了13.8.4&#xff0c;后来查阅了相关资料才知道这并不是自己写错了。 场景复现&…

你知不知道ai如何绘画的

有没有想要自己能绘画一幅有艺术感的画呢&#xff1f;想自己也能将自己所想的事、物或景绘画出来呢&#xff1f;其实你不用担心你的绘画功底不行&#xff0c;因为现在有一门ai绘画的技术&#xff0c;它可以将你提供的信息用智能技术自动绘画&#xff0c;你也可以把它当做一门新…