C++实现红黑树

#pragma once
#include<iostream>
using namespace std;

enum COLOR{BLACK,RED};

template<class K,class V>
struct RBTreeNode
{
    RBTreeNode<K, V>* _left;
    RBTreeNode<K, V>* _right; 
    RBTreeNode<K, V>* _pParent;
    pair<K, V> _value;//pair是一个接受两个模板类型的模板类,
                      //其中有两个变量,第一个是first相当于模板参数K,第二个是second,相当于模板参数V;
    COLOR _color;//当前节点的颜色

    RBTreeNode(const K& key = K(), const V& value = V(), COLOR color = RED)
        : _left(NULL)
        , _right(NULL)
        , _pParent(NULL)
        ,_value(key,value)
        , _color(color)
    {}
};



template<class K,class V>
class RBTree
{
    typedef RBTreeNode<K, V> Node;
    typedef Node* pNode;

public:
    RBTree()
        :_pRoot(NULL)
    {}

    bool InsertUnique(const pair<K,V>& value)
    {  
        //树为空
        if (_pRoot == NULL)
        {
            _pRoot = new Node(value.first, value.second,BLACK);
            return true;
        }
        //树不为空,找当前结点的插入位置
        pNode pCur = _pRoot;
        pNode parent = pCur;
        while (pCur)
        {
            if (value.first < pCur->_value.first)
            {
                parent = pCur;
                pCur = pCur->_left;
            }
            else if (value.first>pCur->_value.first)
            {
                parent = pCur;
                pCur = pCur->_right;
            }
            else
                return false;
        }

        //找到当前结点,将新节点插入当前位置
        pCur = new Node(value.first, value.second);
        if (value.first < parent->_value.first)
            parent->_left = pCur;
        else
            parent->_right = pCur;
        pCur->_pParent = parent;

            //更新结点的颜色
            if (parent->_color == RED)
            {
                while (parent && parent->_color == RED)
                {
                    //父亲结点的颜色是红色的
                    pNode GrandFather = parent->_pParent;
                    if (parent == GrandFather->_left)
                    {
                        pNode unclue = GrandFather->_right;
                        //情况三  叔叔结点存在,并且颜色为红
                        if (unclue&&unclue->_color == RED)
                        {
                            parent->_color = BLACK;
                            unclue->_color = BLACK;
                            GrandFather->_color = RED;
                            //继续向上调整
                            pCur = GrandFather;
                            parent = pCur->_pParent;
                        }
                        else 
                        {

                            //情况四:叔叔的结点不存在或者叔叔结点存在,颜色为黑色
                            if (pCur == parent->_right)
                            {
                                //情况五  当前结点在父节点的右子树上,先进行左旋,变成情况四
                                _RotateL(parent);
                                swap(parent, pCur);
                            }

                            GrandFather->_color = RED;
                            parent->_color = BLACK;
                            _RotateR(GrandFather);
                            break;
                        }
                    }
                    else
                    {
                        pNode unclue = GrandFather->_left;
                        //情况三 叔叔结点存在,并且颜色为红
                        if (unclue&&unclue->_color == RED)
                        {
                            unclue->_color = BLACK;
                            parent->_color = BLACK;
                            GrandFather->_color = RED;
                            pCur = GrandFather;
                            parent = pCur->_pParent;
                        }
                        else
                        {
                            //情况四  叔叔的结点不存在或者叔叔结点存在,颜色为黑色
                            if (pCur == parent->_left)
                            {
                                //情况五  当前结点在父节点的左子树上,先进行右旋,变成情况四
                                _RotateR(parent);
                                swap(parent, pCur);
                            }
                            parent->_color = BLACK;
                            GrandFather->_color = RED;
                            _RotateL(GrandFather);
                            break;
                        }
                    }
                }   
             }
            _pRoot->_color = BLACK;
        return true;
    }

    void InOrder()
    {
        _InOrder(_pRoot);
    }

    bool IsRBTree()
    {
        if (_pRoot == NULL)
            return true;

        if (RED == _pRoot->_color)
        {
            cout << "根节点为红色,不满足性质2" << endl;
            return false;
        }

        size_t blackCount = 0;
        pNode pCur = _pRoot;
        while (pCur)
        {
            if (pCur->_color == BLACK)
                ++blackCount;
            pCur = pCur->_left;
        }
        size_t pathCount = 0;
        return _IsRBTree(_pRoot, pathCount, blackCount);
    }

private:
    //blackCount:第一条路径上黑色结点的个数
    //pathCount:其他单条路径上的黑色结点的个数
    bool _IsRBTree(pNode pRoot, size_t pathCount,size_t blackCount)
    {
        if (pRoot == NULL)
        {
            return true;
        }

        if (pRoot->_color == BLACK)
            ++pathCount;

        pNode pParent = pRoot->_pParent;
        if (pParent&&pRoot->_color == RED&&pParent->_color == RED)
        {
            cout << "有连在一起的红色结点" << endl;
            return false;
        }

        if (pRoot->_left == NULL&&pRoot->_right == NULL)
        {
            if (pathCount != blackCount)
            {
                cout << "路径中黑色结点个数不同" << endl;
                return false;
            }
        }

        return _IsRBTree(pRoot->_left, pathCount, blackCount) && _IsRBTree(pRoot->_right, pathCount, blackCount);
    }


    void _InOrder(pNode pRoot)
    {
        if (pRoot)
        {
            _InOrder(pRoot->_left);
            cout << "<" << pRoot->_value.first << "," << pRoot->_value.second << ">"<<endl;
            _InOrder(pRoot->_right);
        }
    }

    void _RotateL(pNode parent)
    {
        pNode pSubR = parent->_right;
        pNode pSubRL = parent->_left;
        parent->_right = pSubRL;
        if (pSubRL)
            pSubRL->_pParent = parent;

        pSubR->_left = parent;
        pNode pParent = parent->_pParent;
        parent->_pParent = pSubR;
        pSubR->_pParent = pParent;

        if (pParent == NULL)
        {
            _pRoot = pSubR;
            pSubR->_pParent = NULL;
        }
        else
        {
            if (pParent->_left == parent)
                pParent->_left = pSubR;
            else
                pParent->_right = pSubR;
        }
    }

    void _RotateR(pNode parent)
    {
        pNode pSubL = parent->_left;
        pNode pSubLR = pSubL->_right;
        parent->_left = pSubLR;
        if (pSubLR)
            pSubLR->_pParent = parent;

        pSubL->_right = parent;
        pNode pParent = parent->_pParent;
        parent->_pParent = pSubL;
        pSubL->_pParent = pParent;

        if (pParent == NULL)
        {
            _pRoot = pSubL;
            pSubL->_pParent = NULL;
        }
        else
        {
            if (pParent->_left == parent)
                pParent->_left = pSubL;
            else
                pParent->_right = pSubL;
        }       
    }
private:
    pNode _pRoot;
};


void TestRBTree()
{
    //红黑树一定是二叉搜索树
    int a[] = { 10, 7, 8, 15, 5, 6, 11, 13, 12 };
    RBTree rbt;
    for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
        rbt.InsertUnique(pair(a[i], i));

    rbt.InOrder();
    cout << endl;

    if (rbt.IsRBTree())
        cout << "是红黑树" << endl;
    else
        cout << "不是红黑树" << endl;
}

你可能感兴趣的:(C++实现红黑树)