JavaScript数据结构与算法6

82 阅读4分钟

参考

平衡二叉树(Balance Tree)

  • 如果插入的数据是连续的数据,则会使得二叉搜索树的深度很大(非平衡树),则此时的BST就类似链表的遍历查找,使得查找效率低

    • 如:9、8、7、6、5、4......
  • 因此需要将BST进行平衡化,来解决这些问题

    • AVL(平衡的二叉搜索树)
    • 红黑树(平衡的二叉搜索树)

红黑树(Red Black Tree)

  • 在五大规则下构成平衡的二叉搜索树(红黑树)

    • 节点是红色或黑色
    • 根节点是黑色
    • 每个叶节点都是黑色的空节点
    • 每个红色节点的两个子节点都是黑色
    • 树中不可能出现两个连续的红色节点
    • 任意节点到其子树下的叶节点所经路径的所有黑色节点个数相同
  • 结论:从根节点到叶节点的最长路径不会超过最短路径的2倍

    • 最短路径:全是黑色节点
    • 最长路径:黑色节点和红色节点交替,然后黑色节点比红色节点多一个
    • 因此在这五条规则下能形成相对平衡的二叉树
  • 插入newNode新节点时,如何保持树仍是红黑树?

    • 换色:将节点由红变黑 或 黑变红
    • 左旋转:以根X逆时针旋转,其左子树向左平移成为原根X的右子树
      • a、b、c也可以为空节点,非空也行
    • 右旋转:以根Y顺时针旋转,其右子树向右平移成为原根Y的左子树
      • 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必为黑色
      • 1、newNode是parent的左子节点
        • -> parent变为黑色,grandParent变为红色,以grandParent为根,右旋转
      • 2、newNode是parent的右子节点
        • -> 以parent为根,左旋转,再把parent作为新插入的红色节点(变成情况1)
        • 再把newNode变为黑色、grandParent变为红色、以grandParent为根,右旋转
  • 代码实现太复杂,再抽时间去实现它,举个案例帮助理解

    • 案例1:依次插入10、9、8、7、6、5、4、3、2、1
      • 插入newNode(10),符合情况一
        • 变成黑色
      • 插入newNode(9),符合情况二
        • 直接插入
      • 插入newNode(8),符合情况四
        • Parent(9)变黑,grandParent(10)变红,以grandParent(10)为根进行右旋转
      • 插入newNode(7),符合情况三
        • Parent(8)、uncle(10)变黑,grandParent(9)变红
        • 此时根节点(9)为红色,符合情况一,变色
      • 插入newNode(6),符合情况四
        • parent(7)变为黑色,grandParent(8)变为红色,以grandParent(8)为根,右旋转
      • 插入newNode(5),符合情况三
        • parent(6)变为黑色,uncle(8)变为黑色,grandParent(7)变为红色
      • 插入newNode(4),符合情况四
        • parent(5)变为黑,grandParent(6)变为红色,以grandParent(6)为根,右旋转
      • 插入newNode(3),符合情况三
        • parent(4)、uncle(6)变黑,grandParent(5)变红
      • 把5看作newNode,符合情况四,parent(7)变为黑色,grandParent(9)变为红色,以grandParent(9)为根,右旋转
      • 插入newNode(2),符合情况四
        • parent(3)变为黑色,grandParent(4)变为红色,以grandParent(4)为根,右旋转
      • 插入newNode(1),符合情况三
        • parent(2)、uncle(4)变为黑色,grandParent(3)变为红色
        • 此时把3看作是newNode,属于情况三
          • parent(5)、uncle(9)变为黑色,grandParent(7)变为红色
          • 此时属于情况一,根节点(7)变为黑色
      • 因为上述没出现情况5,所以再插入newNode(1.5),属于情况5
        • 以parent(1)为根,左旋转
        • 此时把parent(1)看作是newNode,它的parent(1.5)变为黑色,grandParent(2)变为红色,再以grandParent(2)为根,右旋转