tree知识点(持续更新)

二叉查找树

二叉查找树,Binary Search Tree[BST],也称有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或具有下列性质的二叉树

1.若任意节点的左子树不为空,则左子树上所有节点的值均小于它的根节点的值

2.若任意节点的右子树不为空,则右子树上所有节点的值均大于它的根节点的值

3.任意节点的左右子树也分别是二叉查找树

4.没有键值相等的节点

因为一棵由 n 个节点随机构造的二叉树高度为 lgN,所以一般操作的执行时间为 O(lgN)

2021-03-30-13-45-1720210330134516

上图,结合二叉查找树的三条约束来看,没有什么问题,下图依旧符合上面三条约束,却是存在问题的

2021-03-30-13-44-5720210330134457

二叉树若退化成了一颗具有 n 个节点的线性链后,操作的最坏时间复杂度为 O(N)

红黑树会通过一些性质使树相对平衡,使得最终查找、插入、删除的时间复杂度最坏情况下依然为 O(lgN)

红黑树

红黑树,Red-Black Tree[RBT],是一个自平衡(不是绝对的平衡)的二叉查找树(BST),树上的每个节点都遵循下面的规则:

1.每个节点要么是红的,要么是黑色

2.根节点是黑色的

3.每个叶子节点(叶子节点即指树尾端 nil 指针或 NULL 节点)是黑色

4.如果一个节点是红色,那么它的两个儿子是黑色

5.对于任一节点而言,其到叶节点的每一条路径都包含相同数目的黑色节点

正是红黑树的这 5 条性质,使得一棵 n 个节点的红黑树始终保持了 lgN 的高度,也就是红黑树查找、插入、删除的最坏时间复杂度为 lgN

2021-03-30-15-42-2920210330154228

红黑树的旋转与变色

当我们在对红黑树进行插入或删除等操作时,对树的结构进行了修改,可能会违背红黑树的性质

为了继续保持红黑树的性质,我们会进行两种操作:

1.recolor(变色,重新标记红色或黑色)

2.rotation(旋转)

先尝试 recolor,如果 recolor 不能达到红黑树的要求,就尝试 rotation

步骤:

假设新插入的节点为 X

  • 1.将新插入的节点标记为红色

  • 2.如果 X 是根节点(root),则标记为黑色

  • 3.如果 X 不是根节点且 X 的 parent 不是黑色

    • 3.1 如果 X 的 uncle(叔叔)是红色

      • 3.1.1 将 parent 和 uncle 标记为黑色

      • 3.1.2 将 grand parent(祖父)标记为红色

      • 3.1.3 将 G 变成新的 X,然后重复步骤 2、3

    • 3.2 如果 X 的 uncle(叔叔)是黑色,要分成四种情况处理

      • 3.2.1 左左(P 是 G 的左儿子,X 是 P 的左儿子)

      • 3.2.2 左右(P 是 G 的左儿子,X 是 P 的右儿子)

      • 3.2.3 右右(P 是 G 的右儿子,X 是 P 的右儿子)

      • 3.2.4 右左(P 是 G 的右儿子,X 是 P 的左儿子)

uncle 是红色

1.将新插入的节点 X 标记为红色

2.发现 X 的 parent(P)同样为红色,这违反了红黑树的第三条规则:不能有两个连续相邻的红色节点

3.发现 X 的 uncle(U)同样为红色

4.将 P 和 U 标记为黑色

5.将 X 和 X 的 grand parent (G)标记为相同的颜色,即红色,将 G 设为新的 X,继续重复 2、3

6.发现 G 是根节点,标记为黑色

7.结束

2021-03-30-16-59-1120210330165910

左左

想象这是一根绳子,手提起 P 点,然后变色

2021-03-30-17-12-2220210330171222

左右

左旋:使 X 的父节点 P 被 X 取代,同时父节点 P 成为 X 的左孩子,然后再应用左左情况

2021-03-30-17-21-4420210330172143

右右

与左左情况一样,想象成一根绳子

2021-04-01-11-14-1720210401111416

右左

右旋:使 X 的父节点 P 被 X 取代,同时父节点 P 成为 X 的右孩子,然后再应用右右情况

2021-04-01-11-25-2220210401112522