RBTree——红黑树

红黑树是一种二叉搜索树,通过颜色属性确保最长路径不超过最短路径的两倍,保证近似平衡。它是AVL树的近似平衡替代,广泛应用于STL容器。本文介绍了红黑树的性质、插入操作的五种情况以及如何判断一棵树是否为红黑树。
摘要由CSDN通过智能技术生成

红黑树:

红黑树是一棵二叉搜索树,它在每个节点上增加了一个存储位来表示结点的颜色,红色或黑色(Red或Black)
通过对任何一条从根到叶子简单路径上的颜色来约束,红黑树保证最长路径不超过最短路径的两倍,从而达到近似平衡。

红黑树必须满足的性质:
1,每个节点不是红色就是黑色。
2,根节点必须为黑色。
3,如果一个节点是红色,则它的两个子节点是黑色
(即不能有两个连续的红色节点)。
4,对每个节点,从该节点到其所有后代的叶子节点的简单路径上,均包含相同数目的黑色节点。
5,每个叶子节点都是黑色(这里的叶子节点指NIL结点(空结点))(如果是空结点默认为黑色)。

我们可以先来思考一个简单的问题:
为什么红黑树加上了上面的颜色约束性质,它可以保证最长的路径不超过最短路径的两倍?

我们想一下最短路径应该是全黑,最长路径应该是红黑红黑相间。这么看来,它就可以保证最长路径不超过最短路径的两倍。

学完AVL树,接触红黑树时,它们是非常相似的,都会插入删除之后调节平衡,AVL树通过平衡因子调节平衡,红黑树通过颜色约束平衡,我们把AVL树称为高度平衡的二叉搜索树,而红黑树是近似平衡的二叉搜索树
所以在插入,删除上,AVL树旋转的次数比红黑树多,所以红黑树的插入,删除效率更高。
在应用中,红黑树应用更为广泛,在STL中,set,map,multiset,multimap的底层实现都是通过红黑树来完成的

红黑树的节点结构:
因为我们用颜色约束平衡,所以我们创建一个枚举类型来保存结点的颜色

代码实现

enum Color
{
    RED,
    BLACK,
};

template<class K, class V>
struct RBTreeNode
{
   
    RBTreeNode<K, V>* _left;
    RBTreeNode<K, V>* _right;
    RBTreeNode<K, V>* _parent;

    K _key;
    V _value;
    Color _col;

    RBTreeNode(const K& key, const V& value)
        :_left(NULL)
        , _right(NULL)
        , _parent(NULL)
        , _key(key)
        , _value(value)
        , _col(RED)
    {}
};

插入:
我们将红黑树的插入分为五种情况:
第一种:
范甘迪

第二种:
你

情况二具体情况:1,u不存在
如上图:如果u不存在,那么,a,b,c,d,e也一定都不存在
就
u存在为黑:
如情况二的图:如果u存在为黑,那么,d,e不一定存在,是下图变上去的:
好看
第三种:
脚后跟

第四种:第四种情况与第二种情况是接近的,不同的是:p是g的右孩子,cur是p的右孩子。我们要进行的是左单旋。

第五种:第五种情况与第三种情况是接近的,不同的是:p是g的右孩子,cur是p的左孩子,要先进行右单旋,然后变为第四种情况。
最后两种就不用图演示了,相信看完前三种情况,最后两种也一定可以清除。

代码实现:

bool Insert(const K& key,const V& value)
    {
        if (_root == NULL)
        {
            _root = new Node(key,value);
            _root->_col = BLACK;

            return true;
        }
        Node* parent = NULL;
        Node* cur = _root;
        while (cur)
        {
            if (cur->_key > key)
            {
                parent = cur;
                cur = cur->_left;
            }
            else if (cur->_key < key)
            {
                parent = cur;
                cur = cur->_right;

            }
            else
            {
                return false;
            }
        }
        //找到插入位置
        cur = new Node(key, value);
        if (parent->_key < key)
        {
            parent->_right = cur;
            cur->_parent = parent;
        }
        else
        {
            parent->_left = cur;
            cur->_parent = parent;
        }
        while (parent&&parent->_col == RED)
        {
            Node* grandparent = parent->_parent;
            if (parent == grandparent->_left)
            {
                Node* uncle = grandparent->_right;
                if (uncle&&uncle->_col == RED)
                {
                    parent->_col = BLACK;
                    uncle->_col 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值