红黑树-RBTree

先来说说红黑树是什么吧

红黑树也是一种二叉搜索树,它给每个节点上存储了一个来表示节点的颜色,可以是BLACK,也可以是RED。通过对任何一个从根节点到叶子节点路径上的颜色的约束来达到一个近似平衡的一棵树。红黑树要求最长路径不超过最短路径的两倍。


红黑树满足以下性质:
1、每个节点的颜色不是红色的就是黑色的。
2、根节点的颜色为黑色的。
3、不能有连续的红节点(有父子关系的节点的颜色不能同时为红色)。
4、对每条路径而言,黑色节点的个数必须是相等的。
5、每个叶子节点的颜色是黑色的(这里指的叶子节点为NULL节点)。


接下来,我们来讨论一下插入的时候会有哪几种情况。
特别声明:以下我们插入的节点的颜色默认是红色的。
1、根节点为NULL时,直接插入即可。

2、当父节点的颜色为黑色时,直接插入即可。

3、当父节点的颜色为红色时:
当p节点为红色时,如果u节点存在且为红色,将pp节点的颜色更改为红色,p节点和u节点的颜色更改为黑色。如下图所示
这里写图片描述
当cu节点为p的左节点,p节点为红色时,u的颜色为黑色或者是不存在时,右旋,如下图所示:
这里写图片描述
当cu节点为p的右节点,p节点为红色时,u的颜色为黑色或者是不存在时,先左旋再右旋,如下图所示:
这里写图片描述


接下来,我们举个实例来看看到底如何来实现的
将a[] = { 5,3,4,1,7,8,2,6,0,9 };依次插入。
插入5:

插入3:

插入4(先左旋在右旋):

插入1:

插入7:

插入8(左旋):

插入2(先左旋再右旋):

插入6(p节点和u节点同时为红色)

插入0(p节点和u节点同时为红色):

插入9:


代码实现

#pragma once
enum Color
{
    BLACK,
    RED
};
template<class V>
struct RBTreeNode
{
    RBTreeNode<V>* _left;
    RBTreeNode<V>* _right;
    RBTreeNode<V>* _parent;
//  K _key;
    V _v;
    Color _col;
    RBTreeNode(const V& v, Color col = RED)
        :_left(NULL)
        ,_right(NULL)
        ,_parent(NULL)
        ,_v(v)
        ,_col(col)
    {}
};
template<class V, class Ref, class Ptr>
struct RBTreeIterator
{
    typedef RBTreeNode<V> Node;
    typedef RBTreeIterator<V, Ref, Ptr> Iterator;
    typedef RBTreeIterator<V, const Ref, const Ptr> ConstIterator;
    typedef RBTreeIterator<V, Ref, Ptr> Self;
    Node* _node;
    RBTreeIterator(Node* node)
        :_node(node)
    {}
    Ref operator*()
    {
        return _node->_v;
    }
    Ptr operator->()
    {
        return &(operaotr*());
    }
    Self& operator++()
    {
        if (_node->_right)
        {
            Node* subright = _node->_right;
            while (subright->_left)
            {
                subright = subright->_left;
            }
            _node = subright;
        }
        else
        {

        }
    }
};
template<class V>
class RBTree
{
public:
    typedef RBTreeNode<V> Node;

    RBTree()
        :_root(NULL)
    {}
    void RotateL(Node* parent)
    {
        Node* subR = parent->_right;
        Node* subRL = subR->_left;

        parent->_right = subRL;
        if (subRL)
            subRL->_parent = parent;
        subR->_left = parent;

        Node* ppNode = parent->_parent;
        parent->_parent = subR;

        if (_root == parent)
        {
            _root = subR;
            subR->_parent = NULL;
        }
        else
        {
            if (ppNode->_right == parent)
                ppNode->_right = subR;
            else
                ppNode->_left = subR;
            subR->_parent = ppNode;
        }
    //  _root->_parent = NULL;
    }
    void RotateR(Node* parent)
    {
        Node* subL = parent->_left;
        Node* subLR = subL->_right;

        parent->_left = subLR;
        if (subLR)
            subLR->_parent = parent;
        subL->_right = parent;

        Node* ppNode = parent->_parent;
        parent->_parent = subL;

        if (_root == parent)
        {
            _root = subL;
            subL->_parent = NULL;
        }
        else
        {
            if (ppNode->_left == parent)
                ppNode->_left = subL;
            else
                ppNode->_right = subL;

            subL->_parent = ppNode;
        }
        _root->_parent = NULL;
    }

    bool Insert(const V& v)
    {
        if (_root == NULL)
        {
            _root = new Node(v);
            _root->_col = BLACK;
            return true;
        }
        Node* cur = _root;
        Node* parent = NULL;
        while (cur)
        {
            if (cur->_v > v)
            {
                parent = cur;
                cur = cur->_left;
            }
            else
            {
                parent = cur;
                cur = cur->_right;
            }
        }
        cur = new Node(v);
        if (parent->_v > v)
        {
            parent->_left = cur;
            cur->_parent = parent;
        }
        else
        {
            parent->_right = cur;
            cur->_parent = parent;
        }

        //判断颜色
        while (parent && parent->_col == RED)
        {
            Node* grandparent = parent->_parent;
            if (grandparent && grandparent->_col == BLACK)
            {
                if (parent == grandparent->_left)
                {
                    Node* uncle = grandparent->_right;
                    if (uncle && uncle->_col == RED)
                    {
                        uncle->_col = BLACK;
                        parent->_col = BLACK;
                        if(grandparent->_parent)
                            grandparent->_col = RED;
                        cur = grandparent;
                        parent = cur->_parent;
                    }
                    else
                    {
                        if (cur == parent->_right)
                        {
                            RotateL(parent);
                            swap(cur, parent);
                        }
                        RotateR(grandparent);
                        grandparent->_col = RED;
                        parent->_col = BLACK;
                    }

                }
                else
                {
                    Node* uncle = grandparent->_left;
                    if (uncle && uncle->_col == RED)
                    {
                        parent->_col == uncle->_col == RED;
                        if(grandparent->_parent)
                            grandparent->_col = BLACK;

                        cur = grandparent;
                        parent = cur->_parent;
                    }
                    else
                    {
                        if (cur == parent->_left)
                        {
                            RotateR(parent);
                            swap(cur, parent);
                        }
                        RotateL(grandparent);
                        parent->_col = BLACK;
                        grandparent->_col = RED;
                    }

                }
            }
            else
            {
                grandparent->_col == BLACK;
                break;
            }

        }

    }
    bool IsBalance()
    {
        if (_root && _root->_col == RED)
            return false;
        int k = 0;
        Node* cur = _root;
        while (cur)
        {
            if (cur->_col == BLACK)
                ++k;
            cur = cur->_left;
        }

        int blacknum = 0;
        return _IsBalance(_root, k, blacknum);
    }
    bool _IsBalance(Node* root, int k, int blacknum)
    {
        if (root == NULL)
        {
            if (k != blacknum)
            {
                cout << "黑色节点的数量不相同" << " " << endl;
                return false;
            }
            return true;
        }
        if (root->_col == RED && root->_parent->_col == RED)
        {
            cout << "存在连续的红节点" << root->_v << " " << endl;
            return false;
        }
        if (root->_col != RED && root->_col != BLACK)
        {
            cout << "节点的颜色既不是黑色的也不是红色的" << root->_v << " " << endl;
            return false;
        }
        if (root->_col == BLACK)
        {
            ++blacknum;
        }
        return _IsBalance(root->_left, k, blacknum)
            && _IsBalance(root->_right, k, blacknum);
    }
    void InOrder()
    {
         _InOrder(_root);
         cout << endl;
    }
    void _InOrder(Node* root)
    {
        if (root == NULL)
            return;

        _InOrder(root->_left);
        cout << root->_v << " ";
        _InOrder(root->_right);
    }
protected:
    Node* _root;
};
void TestRBTree()
{
    int a[] = { 5,3,4,1,7,8,2,6,0,9 };
    RBTree<int> t;
    for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
    {
        t.Insert(a[i]);
        cout << a[i] << t.IsBalance() << " ";
    }
    cout << endl;
    t.InOrder();
    //t.IsBalance();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值