参考
- b站视频链接:www.bilibili.com/video/BV1x7…
- 参考的github笔记:github.com/XPoet/JS-Da…
平衡二叉树(Balance Tree)
-
如果插入的数据是连续的数据,则会使得二叉搜索树的深度很大(非平衡树),则此时的BST就类似链表的遍历查找,使得查找效率低
- 如:9、8、7、6、5、4......
- 如:9、8、7、6、5、4......
-
因此需要将BST进行平衡化,来解决这些问题
- AVL(平衡的二叉搜索树)
- 红黑树(平衡的二叉搜索树)
红黑树(Red Black Tree)
-
在五大规则下构成平衡的二叉搜索树(红黑树)
- 节点是红色或黑色
- 根节点是黑色
- 每个叶节点都是黑色的空节点
- 每个红色节点的两个子节点都是黑色
- 树中不可能出现两个连续的红色节点
- 任意节点到其子树下的叶节点所经路径的所有黑色节点个数相同
-
结论:从根节点到叶节点的最长路径不会超过最短路径的2倍
- 最短路径:全是黑色节点
- 最长路径:黑色节点和红色节点交替,然后黑色节点比红色节点多一个
- 因此在这五条规则下能形成相对平衡的二叉树
-
插入newNode新节点时,如何保持树仍是红黑树?
- 换色:将节点由红变黑 或 黑变红
- 左旋转:以根X逆时针旋转,其左子树向左平移成为原根X的右子树
- a、b、c也可以为空节点,非空也行
- a、b、c也可以为空节点,非空也行
- 右旋转:以根Y顺时针旋转,其右子树向右平移成为原根Y的左子树
- a、b、c也可以为空节点,非空也行
- a、b、c也可以为空节点,非空也行
- 换色:将节点由红变黑 或 黑变红
-
插入newNode时,parent、uncle、grandParent不同的情况
- newNode一般为红色时,需要调整红黑树较小
- newNode:插入的新节点
- borther:newNode的兄弟节点
- parent:newNode的父节点
- uncle:parent的兄弟节点
- grandParent:parent的父节点
- 一、空树:将newNode变为黑色
- 二、parent是黑色:直接插入到它的空子节点,newNode扩展两个黑色的空节点
- 三、parent、uncle为红色,此时grandParent必为黑色
- -> parent、uncle变为黑色,grandParent变为红色
- -> parent、uncle变为黑色,grandParent变为红色
- 四、parent为红色,uncle为黑色,此时grandParent必为黑色
- 1、newNode是parent的左子节点
- -> parent变为黑色,grandParent变为红色,以grandParent为根,右旋转
- -> parent变为黑色,grandParent变为红色,以grandParent为根,右旋转
- 2、newNode是parent的右子节点
- -> 以parent为根,左旋转,再把parent作为新插入的红色节点(变成情况1)
- 再把newNode变为黑色、grandParent变为红色、以grandParent为根,右旋转
- -> 以parent为根,左旋转,再把parent作为新插入的红色节点(变成情况1)
- 1、newNode是parent的左子节点
-
代码实现太复杂,再抽时间去实现它,举个案例帮助理解
- 案例1:依次插入10、9、8、7、6、5、4、3、2、1
- 插入newNode(10),符合情况一
- 变成黑色
- 变成黑色
- 插入newNode(9),符合情况二
- 直接插入
- 直接插入
- 插入newNode(8),符合情况四
- Parent(9)变黑,grandParent(10)变红,以grandParent(10)为根进行右旋转
- Parent(9)变黑,grandParent(10)变红,以grandParent(10)为根进行右旋转
- 插入newNode(7),符合情况三
- Parent(8)、uncle(10)变黑,grandParent(9)变红
- 此时根节点(9)为红色,符合情况一,变色
- 插入newNode(6),符合情况四
- parent(7)变为黑色,grandParent(8)变为红色,以grandParent(8)为根,右旋转
- parent(7)变为黑色,grandParent(8)变为红色,以grandParent(8)为根,右旋转
- 插入newNode(5),符合情况三
- parent(6)变为黑色,uncle(8)变为黑色,grandParent(7)变为红色
- parent(6)变为黑色,uncle(8)变为黑色,grandParent(7)变为红色
- 插入newNode(4),符合情况四
- parent(5)变为黑,grandParent(6)变为红色,以grandParent(6)为根,右旋转
- parent(5)变为黑,grandParent(6)变为红色,以grandParent(6)为根,右旋转
- 插入newNode(3),符合情况三
- parent(4)、uncle(6)变黑,grandParent(5)变红
- parent(4)、uncle(6)变黑,grandParent(5)变红
- 把5看作newNode,符合情况四,parent(7)变为黑色,grandParent(9)变为红色,以grandParent(9)为根,右旋转
- 插入newNode(2),符合情况四
- parent(3)变为黑色,grandParent(4)变为红色,以grandParent(4)为根,右旋转
- parent(3)变为黑色,grandParent(4)变为红色,以grandParent(4)为根,右旋转
- 插入newNode(1),符合情况三
- parent(2)、uncle(4)变为黑色,grandParent(3)变为红色
- 此时把3看作是newNode,属于情况三
- parent(5)、uncle(9)变为黑色,grandParent(7)变为红色
- 此时属于情况一,根节点(7)变为黑色
- parent(2)、uncle(4)变为黑色,grandParent(3)变为红色
- 因为上述没出现情况5,所以再插入newNode(1.5),属于情况5
- 以parent(1)为根,左旋转
- 此时把parent(1)看作是newNode,它的parent(1.5)变为黑色,grandParent(2)变为红色,再以grandParent(2)为根,右旋转
- 以parent(1)为根,左旋转
- 插入newNode(10),符合情况一
- 案例1:依次插入10、9、8、7、6、5、4、3、2、1