红黑树

二叉查找树

Binary Search Tree 「BST」,特性:

  • 某节点的左子树节点值仅包含小于该节点值
  • 某节点的右子树节点值仅包含大于该节点值
  • 左右子树每个也必须是二叉查找树

二叉树很容易出现树分叉平衡,查找次数或时间复杂度 O(h)可能会随着一边长无限增长
而红黑树其实就是去除二叉查找树不平衡的解决方案,从而达到树的平衡

红黑树定义

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

  • 每个节点都有红色或黑色
  • 树的根始终是黑色的
  • 没有两个相邻的红色节点(红色节点不能有红色父节点或红色子节点)
  • 从节点(包括根)到其任何后代NULL节点(叶子结点下方挂的两个空节点,并且认为他们是黑色的)的每条路径都具有相同数量的黑色节点

recolor 与 rotation

如何构成红黑树,先尝试 recolor,如果 recolor 不能达到红黑树的 4 点要求,然后我们尝试 rotation

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

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

  3. 如果 X 的 parent 不是黑色,同时 X 也不是 root:
    3.1. 如果 X 的 uncle (叔叔) 是红色
    3.1.1. 将 parent 和 uncle 标记为黑色
    3.1.2. 将 grand parent (祖父) 标记为红色
    3.1.3. 让 X 节点的颜色与 X 祖父的颜色相同,然后重复步骤 2、3

     ![img](https://segmentfault.com/img/remote/1460000019855254?w=598&h=264)
    

    3.2. 如果 X 的 uncle (叔叔) 是黑色,我们要分四种情况处理(用到旋转)
    3.2.1 左左 (P 是 G 的左孩子,并且 X 是 P 的左孩子)

     想象这是一根绳子,手提起 P 节点,然后变色即可
     ![img](https://segmentfault.com/img/remote/1460000019855255?w=621&h=231)
    

    3.2.2 左右 (P 是 G 的左孩子,并且 X 是 P 的右孩子)

     左旋: 使 X 的父节点 P 被 X 取代,同时父节点 P 成为 X 的左孩子,然后再应用 左左情况
     ![img](https://segmentfault.com/img/remote/1460000019855256?w=762&h=304)
    

    3.2.3 右右 (和 3.2.1 镜像过来,恰好相反)

     与左左情况一样,想象成一根绳子
     ![img](https://segmentfault.com/img/remote/1460000019855257?w=646&h=294)
    

    3.2.4 右左 (和 3.2.2 镜像过来,恰好相反)

     右旋: 使 X 的父节点 P 被 X 取代,同时父节点 P 成为 X 的右孩子,然后再应用 右右情况
     ![img](https://segmentfault.com/img/remote/1460000019855258?w=727&h=312)
    

参考

https://segmentfault.com/a/1190000020118044