红黑树

红黑树的定义:红黑树是一棵二叉搜索树,它在每个结点上增加了一个存储位来表示结点的颜色,可以是red或者black,通过对任何一条从根节点到叶子结点上的简单路径来约束,红黑树保证最长路径不超过最短路径的两倍,因而近似平衡。
红黑树的性质:
1、每个结点不是红色就是黑色;
2、根节点是黑色的;
3、如果一个节点是红色的,则它的两个叶子结点是黑色的(没有两个连续的红色结点)
4、对于每个结点,从该结点到其所有后代叶子结点的简单路径上,均包含相同数目的黑色结点(每条路径上黑色结点的数量相等)
5、每个叶子结点都是黑色的(此处的叶子结点指的是空结点)


插入结点的简单分析:
情况一:cur为红,p为红,g为黑,u存在且为红
p,u变黑,g变红,然后把g当成cur,继续向上调整。
情况二:cur为红,p为红,g为黑,u不存在/u为黑
p为g的左孩子,cur为p的左孩子,则进行右单旋转;相反,p为g的右孩子,cur为p的右孩子,则进行左单旋转 p、g变色–p变黑,g变红
情况三:cur为红,p为红,g为黑,u不存在/u为黑
p为g的左孩子,cur为p的右孩子,则针对p做左单旋转;相反,p为g的右孩子,cur为p的左孩子,则针对p做右单旋转。此时转换成了情况2。
具体实现:

#include<iostream>
using namespace std;
enum Color{RED,BLACK};
template<typename K,typename V>
struct RBTreeNode
{
    RBTreeNode(K key, V val, Color color = RED)
    : _key(key)
    , _val(val)
    , _Left(NULL)
    , _Right(NULL)
    , _Parent(NULL)
    , _color(color)
    {}
    K _key;
    V _val;
    RBTreeNode<K, V>* _Left;
    RBTreeNode<K, V>* _Right;
    RBTreeNode<K, V>* _Parent;
    Color _color;
};
template<typename K,typename V>
class RBTree
{
    typedef RBTreeNode<K, V> Node;
public:
    RBTree()
        : _pRoot(NULL)
    {}
    bool Insert(const K& key,const V& val)
    {
        if (NULL == _pRoot)
        {
            _pRoot = new Node(key, val, BLACK);
            return true;
        }
        //找插入位置
        Node* pCur = _pRoot;
        Node* parent = NULL;
        while (pCur)
        {
            if (key < pCur->_key)
            {
                parent = pCur;
                pCur = pCur->_Left;
            }
            else if (key > pCur->_key)
            {
                parent = pCur;
                pCur = pCur->_Right;
            }
            else
                return false;
        }
        //插入结点
        pCur = new Node(key, val);
        if (key < parent->_key)
            parent->_Left = pCur;
        else
            parent->_Right = pCur;
        pCur->_Parent = parent;
        //更改结点颜色
        while (pCur != _pRoot && parent->_color == RED)
        {
            Node* grandFather = parent->_Parent;
            if (parent == grandFather->_Left)
            {
                Node* uncle = grandFather->_Right;
                if (uncle && uncle->_color == RED)//--情况1
                {
                    parent->_color = BLACK;
                    uncle->_color = BLACK;
                    grandFather->_color = RED;
                    pCur = grandFather; //继续向上调整
                    parent = pCur->_Parent;
                }
                else//uncle不存在或uncle的color为BLACK -- 情况3
                {
                    if (pCur == parent->_Right)//先左单旋
                    {
                        RotateLeft(parent);
                        swap(parent, pCur);//调整指针,即为情况2
                    }
                    parent->_color = BLACK;
                    grandFather->_color = RED;
                    RotateRight(grandFather);//再右单旋; 如果pCur == parent->_Left直接右单旋(情况2)  
                    break;
                }
            }
            else  //parent == grandFather->_Right
            {
                Node* uncle = grandFather->_Left;
                if (uncle && uncle->_color == RED)//情况1
                {
                    parent->_color = BLACK;
                    uncle->_color = BLACK;
                    grandFather->_color = RED;
                    pCur = grandFather; //继续向上调整
                    parent = pCur->_Parent;
                }
                else//uncle不存在或uncle的color为BLACK -- 情况3
                {
                    if (pCur == parent->_Left)//先右单旋
                    {
                        RotateRight(parent);
                        swap(parent, pCur);//调整指针,即为情况2
                    }
                    parent->_color = BLACK;
                    grandFather->_color = RED;
                    RotateLeft(grandFather);//再左单旋; 如果pCur == parent->_Right直接左单旋(情况2)
                    break;
                }
            }
        }   
        _pRoot->_color = BLACK; //uncle的color为BLACK
        return true;
    }
    void InOrder()
    {
        _InOrder(_pRoot);
        cout << endl;
    }
    bool CheckRBTree()
    {
        if (NULL == _pRoot)
            return true;
        if (_pRoot->_color == RED)
            return false;
        size_t blackCount = 0, k = 0;
        Node* pCur = _pRoot;
        while (pCur)
        {
            if (pCur->_color == BLACK)
                blackCount++;
            pCur = pCur->_Left;
        }
        return _CheckRBTree(_pRoot, blackCount, k);
    }
private:
    void RotateLeft(Node* parent)
    {
        if (NULL == parent)
            return;
        Node* subR = parent->_Right;
        Node* subRL = subR->_Left;
        parent->_Right = subRL;
        if (subRL)
            subRL->_Parent = parent;
        subR->_Left = parent;
        subR->_Parent = parent->_Parent;
        Node* ppParent = parent->_Parent;
        parent->_Parent = subR;
        if (ppParent)
        {
            if (parent == ppParent->_Left)
                ppParent->_Left = subR;
            else
                ppParent->_Right = subR;
        }
        else
        {
            _pRoot = subR;
            subR->_Parent = NULL;
        }
        parent = subR;
    }
    void RotateRight(Node* parent)
    {
        if (NULL == parent)
            return;
        Node* subL = parent->_Left;
        Node* subLR = subL->_Right;
        parent->_Left = subLR;
        if (subLR)
            subLR->_Parent = parent;
        subL->_Right = parent;
        subL->_Parent = parent->_Parent;
        Node* ppParent = parent->_Parent;
        parent->_Parent = subL;
        if (ppParent)
        {
            if (parent == ppParent->_Left)
                ppParent->_Left = subL;
            else
                ppParent->_Right = subL;
        }
        else
        {
            _pRoot = subL;
            subL->_Parent = NULL;
        }
        parent = subL;
    }
    void _InOrder(Node* pRoot)
    {
        if (NULL == pRoot)
            return;
        _InOrder(pRoot->_Left);
        cout << pRoot->_key << " ";
        _InOrder(pRoot->_Right);
    }
    bool _CheckRBTree(Node* pRoot,const size_t blackCount,size_t k)
    {
        if (NULL == pRoot)
            return true;
        if (pRoot->_color == RED)
        {
            if (pRoot->_Parent->_color == RED)
            {
                cout << "不满足性质3!!" << endl;
                return false;
            }
        }
        else
            k++;
        if (pRoot && NULL == pRoot->_Left && NULL == pRoot->_Right)
        {
            if (blackCount == k)
                return true;
            else
            {
                cout << "不满足性质4!!" << endl;
                return false;
            }
        }
        else
        {
            return _CheckRBTree(pRoot->_Left, blackCount, k) && _CheckRBTree(pRoot->_Right, blackCount, k);
        }   
    }
private:
    Node* _pRoot;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值