二叉树之红黑树迭代器

来源:互联网 发布:iis批量绑定域名 编辑:程序博客网 时间:2024/06/05 20:42

红黑事的性质:
1.每个节点不是红色就是黑色。
2.根节点一定是黑色。
3.没有两个连续的红色节点。
4.每个叶子结点道根的路径上,黑色结点的个数都相等。
5.每个叶子结点的空指针域都是黑色的。
通过这些条件的设定,可以保证最长路径上结点的个数不会超过最短路径上节点个数的两倍。
这里写图片描述
这是一种极限情况,但是这种情况不可能出现,因为正在插入每个节点时都需要调整。
红黑树插入时要考虑的几种情况:
1.
如果pParent->_color == BLACK;
直接插入新节点。
2.
当前节点pCur为红色,
双亲节点pParent为红色,
叔叔节点Uncle为红色,
祖父结点grandFather为黑色。
这里写图片描述
3.
当前节点pCur为红色,
双亲节点pParent为红色,
叔叔节点Uncle为黑色或不存在,
祖父结点grandFather为黑色。
若pCur是pParent的左孩子,且pParent是grandFather的左孩子,进行右单旋。
若pCur是pParent的右孩子,且pParent是grandFather的右孩子,进行左单旋。(此处不做详细描述)
这里写图片描述
4.
当前节点pCur为红色,
双亲节点pParent为红色,
叔叔节点Uncle为黑色或不存在,
祖父结点grandFather为黑色。
若pCur是pParent的左孩子,且pParent是grandFather的右孩子,先进行左单旋,左单旋后与情况3相同,所以处理方式也就相同。
若pCur是pParent的右孩子,且pParent是grandFather的左孩子,先进行右单旋,右单旋后与情况3的另一种相同,所以处理方式也就相同。
这里写图片描述
节点结构体:

using namespace std;enum COLOR{    RED,     BLACK};template<class K, class V>struct RBTreeNode{    RBTreeNode(const K& key = K(), const V& value = V(), const COLOR& color = RED)        :_pLeft(NULL)        , _pRight(NULL)        , _pParent(NULL)        , _key(key)        , _value(value)        , _color(color)    {}    RBTreeNode<K, V>* _pLeft;    RBTreeNode<K, V>* _pRight;    RBTreeNode<K, V>* _pParent;    K _key;    V _value;    COLOR _color;};

迭代器:

#include "RBTreeNode.h"template<class K, class V, class Ref, class Pointer>class RBTreeIterator{    typedef RBTreeNode<K , V> Node;    typedef RBTreeIterator<K, V, Ref, Pointer> Self;public:    RBTreeIterator()        : _pNode(NULL)    {}    RBTreeIterator(Node* pNode)        : _pNode(pNode)    {}    RBTreeIterator(RBTreeIterator& it)        : _pNode(it._pNode)    {}    Self& operator++()    {        _Increment();        return *this;    }    Self operator++(int)    {        Self tmp(*this);        _Increment();        return tmp;    }    Self& operator--()    {        _Decrement();        return *this;    }    Self operator--(int)    {        Self tmp(*this);        _Decrement();        return tmp;    }    Ref operator*()    {        return _pNode->_key;    }    const Ref operator*()const     {        return _pNode->_key;    }    Pointer operator->()    {        return &(operator*());    }    const Pointer operator->()const    {        return &(operator*());    }    bool operator==(const Self& it)    {        return _pNode == it._pNode;    }    bool operator!=(const Self& it)    {        return _pNode != it._pNode;    }protected:    //下一个节点    void _Increment()    {        if(_pNode->_pRight)        {            _pNode = _pNode->_pRight;            while(_pNode->_pLeft)                _pNode = _pNode->_pLeft;        }        else        {            Node* pParent = _pNode->_pParent;            while(pParent->_pRight == _pNode)            {                _pNode = pParent;                pParent = pParent->_pParent;            }            if(_pNode->_pLeft != pParent)                _pNode = pParent;        }    }    void _Decrement()    {        //头结点的前一个是它的右孩子        if(_pNode->_pParent->_pParent == _pNode && _pNode->_color == RED)            _pNode = _pNode->_pRight;        if(_pNode->_pLeft)        {            _pNode = _pNode->_pLeft;            while(_pNode->_pRight)                _pNode = _pNode->_pRight;        }        else        {            Node* pParent = _pNode->_pParent;            if(_pNode == pParent->_pLeft)            {                _pNode = pParent;                pParent = pParent->_pParent;            }            _pNode = pParent;        }    }protected:    Node* _pNode;};

插入函数与查找函数:

template<class K, class V>class RBTree{    typedef RBTreeNode<K, V> Node;public:    typedef RBTreeIterator<K, V, K&, K*> Iterator;public:    RBTree()        :_size(0)    {        _pHead = new Node();        _pHead->_pLeft = _pHead;        _pHead->_pRight = _pHead;        _pHead->_pParent = NULL;    }    Iterator Begin()    {        return _pHead->_pLeft;    }    Iterator End()    {        return _pHead;    }    bool Empty()const    {        return _pHead->_pParent == NULL;    }    size_t Size()const    {        return _size;    }    Iterator Find(const K& key)    {        Node* pRoot = GetRoot();        if(pRoot)        {            while(pRoot)            {                if(pRoot->_key == key)                    return pRoot;                else if(pRoot->_key > key)                    pRoot = pRoot->_pLeft;                else                    pRoot = pRoot->_pRight;            }        }        return NULL;    }    bool Insert(const K& key, const V& value)    {        Node* pRoot = _GetRoot();        if(pRoot == NULL)        {            pRoot = new Node(key, value);            pRoot->_pParent = _pHead;            _pHead->_pParent = pRoot;        }        else        {            Node* pCur = pRoot;            Node* pParent = NULL;            while(pCur)            {                if(pCur->_key > key)                {                    pParent = pCur;                    pCur = pCur->_pLeft;                }                else if(pCur->_key < key)                {                    pParent = pCur;                    pCur = pCur->_pRight;                }                else                    return false;            }            pCur = new Node(key, value);            if(pParent->_key > key)                pParent->_pLeft = pCur;            else                pParent->_pRight = pCur;            pCur->_pParent = pParent;            //调整            while(pParent->_color == RED && pRoot != pCur)            {                Node* grandFather = pParent->_pParent;                //如果双亲节点是左孩子                if(pParent == grandFather->_pLeft)                {                    //定义叔叔节点                    Node* Uncle = grandFather->_pRight;                    if(Uncle->_color == RED)//情况二                    {                        pParent->_color = BLACK;                        Uncle->_color = BLACK;                        grandFather->_color = RED;                        pCur = grandFather;                        pParent = pCur->_pParent;                    }                    else                    {                        //先将情况四左旋成情况三                        if(pCur == pParent->_pRight)                        {                            _RotateL(pParent);                            std::swap(pCur, pParent);                        }                        pParent->_color = BLACK;                        grandFather->_color = RED;                        _RotateR(grandFather);                    }                }                else                {                    //定义叔叔节点                    Node* Uncle = grandFather->_pLeft;                    if(Uncle->_color == RED)//情况五                    {                        pParent->_color = BLACK;                        Uncle->_color = BLACK;                        grandFather->_color = RED;                        pCur = grandFather;                        pParent = pCur->_pParent;                    }                    else                    {                        //先将情况七左旋成情况六                        if(pCur == pParent->_pLeft)                        {                            _RotateR(pParent);                            std::swap(pCur, pParent);                        }                        _RotateL(grandFather);                        pParent->_color = BLACK;                        grandFather->_color = RED;                    }                }            }        }        _pHead->_pLeft = _GetMinNode(pRoot);        _pHead->_pRight = _GetMaxNode(pRoot);        _GetRoot()->_color = BLACK;        ++_size;        return true;    }    void InOrder()    {        cout<<"InOrder: ";        _InOrder(_GetRoot());        cout<<endl;    }private:    void _RotateL(Node* pParent)    {        Node* pCur = pParent->_pRight;        Node* pTmp = pCur->_pLeft;        Node* pPParent = pParent->_pParent;        pParent->_pRight = pTmp;        if(pTmp)            pTmp->_pParent = pParent;        pCur->_pLeft = pParent;        pParent->_pParent = pCur;        pParent->_color = RED;        if(pPParent == _pHead)            _pHead->_pParent = pCur;        else        {            if(pPParent->_pLeft == pParent)                pPParent->_pLeft = pCur;            else                pPParent->_pRight = pCur;        }        pCur->_pParent = pPParent;    }    void _RotateR(Node* pParent)    {        Node* pCur = pParent->_pLeft;        Node* pTmp = pCur->_pRight;        Node* pPParent = pParent->_pParent;        pParent->_pLeft = pTmp;        if(pTmp)            pTmp->_pParent = pParent;        pCur->_pRight = pParent;        pParent->_pParent = pCur;        pParent->_color = RED;        if(pPParent == _pHead)            _GetRoot() = pParent;        else        {            if(pPParent->_pLeft == pParent)                pPParent->_pLeft = pCur;            else                pPParent->_pRight = pCur;        }        pCur->_pParent = pPParent;    }    void _InOrder(Node* pRoot)    {        if(pRoot)        {            _InOrder(pRoot->_pLeft);            cout<<pRoot->_key<<" ";            _InOrder(pRoot->_pRight);        }    }    Node* &_GetRoot()    {        return _pHead->_pParent;    }    Node* _GetMinNode(Node* pRoot)    {        while(pRoot->_pLeft)            pRoot = pRoot->_pLeft;        return pRoot;    }    Node* _GetMaxNode(Node* pRoot)    {        while(pRoot->_pRight)            pRoot = pRoot->_pRight;        return pRoot;    }private:    Node* _pHead;    size_t _size;};

检测红黑树:
检测一棵树是不是红黑树,就要根据它的性质来检测,红黑树种有两条很重要的性质,就是性质三(没有两个连在一起的红色节点)和性质四(每条路上的黑色结点个数相等)。
要判断每条路上的黑色结点个数是否相等,首先就要知道其他路上的个数是多少,那么可以先计算出到达最左结点时,黑色结点的个数,再根据这个值来判断其他路上的值是不是和这个值相等,如果不相等则返回false,否则继续判断。

public:    bool CheckRBTree()    {        Node* pRoot = _GetRoot();        size_t k = 0;        if(pRoot == NULL)            return true;        size_t blackCount = 0;        while(pRoot->_pLeft)        {            if(pRoot->_color == BLACK)                ++blackCount;            pRoot = pRoot->_pLeft;        }        return _CheckRBTree(_GetRoot(), blackCount, k);    }private:    bool _CheckRBTree(Node* pRoot, const size_t blackCount, size_t k)    {        if(pRoot == NULL)            return true;        else        {            Node* pParent = pRoot->_pParent;            if(pRoot->_color == RED && pParent->_color == RED)                return false;            if(pRoot->_color == BLACK)            {                k++;            }            if(pRoot->_pLeft == NULL && pRoot->_pRight == NULL)            {                if(k != blackCount)                    return false;                return true;            }        }        return _CheckRBTree(pRoot->_pLeft, blackCount, k) && \            _CheckRBTree(pRoot->_pRight, blackCount, k);    }