红黑树概念

image.png

  • 红黑树是一种二叉搜索树,在每个节点上增加一个存储位,用来存储节点颜色(红或黑)
  • 通过对通过对颜色的限制,确保任意一条从根节点到叶子节点的路径不会比其他路径长出两倍(即最长路径最多只能是最短路径的两倍)
  • 红黑树通过对颜色的控制,从而达到近似平衡(AVL是严格平衡的)
  • AVL树通过旋转方式来控制平衡,而其搜索效率上跟红黑树差不多(红黑树效率要略低)
  • 虽然红黑树效率略低,但是AVL树旋转次数过多,综合来说红黑树更好一些。

红黑树性质

  1. 每个节点只能是红色或者黑色。
  2. 根节点是黑色。
  3. 如果一个节点是红色,那么它的两个子节点就是黑色(如果一个节点是黑色,那么它的子节点可以是红色也可以是黑色)(即不存在连续的红色节点)
  4. 对于每个节点,从该节点到其后代的所有叶子节点的路径上,每条路径的黑色节点数相同(包括最后的空节点)
  5. 所有的空节点都是黑色。
  • 通过上述规则的控制,就可以保证红黑树的最长路径中节点个数不会超过最短路径节点数的两倍。
  • 最长路径一黑一红,最短路径全黑。

红黑树节点定义方式

  • 一般在插入新节点时,默认插入节点颜色为红色,因为默认为黑色节点,一定会破坏规则四,影响较大,但是默认为红色节点,只是有可能破坏规则三。
template<class K,class V>
struct RBTreeNode
{
    RBTreeNode<K, V>* _left;
    RBTreeNode<K, V>* _right;
    RBTreeNode<K, V>* _parent;
    pair<K, V> _kv;  //键值对,存储数据
    Colour _col;  //存储颜色
    RBTreeNode(const pair<K, V>& kv)
        :_left(nullptr)
        , _right(nullptr)
        , _parent(nullptr)
        , _kv(kv)
        , _col(RED)   //默认节点颜色为红色
    {
    }
};

红黑树新增节点的三种情况

  • cur为新增节点,p 为父节点,g为祖父节点,u为叔叔节点(关键看叔叔节点的颜色)
  • 蓝色方框为红黑子树。

情况一:cur为红(在p的左右皆可),p为红,g为黑,u存在且为红

  • 处理方法:变色
  • 将父节点和叔叔节点都变为黑,并且将祖父节点变为红
  • 如果祖父节点的父节点也为红,违反规则三,则继续向上进行变换。
  • 如果祖父节点为根节点,违反规则二,则再将祖父节点变为黑。
    image.png

情况二:cur为红,且在p的左边,p为红,g为黑,u不存在或者存在且为黑

  • cur在父节点的左边。
  • 处理方法:单右旋+变色(祖孙三代是直线关系)
  • 进行右单旋转
  • 将父节点变为黑,祖父节点变为红。
    image.png

情况三:cur为红,且在p的右边,p为红,g为黑,u不存在或者存在且为黑

  • 处理方法:双旋转+变色(祖孙三代是折线关系)
  • 先进行左单旋,再进行右单旋,最后再变色。
    image.png

源码地址

gitee:https://gitee.com/BJFyfwl/Lin...


夜枫微凉
24 声望4 粉丝