红黑树与迭代器的实现

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

红黑树具有一下性质
1、每个节点不是红的就是黑的
2、根节点一定是黑的
3、没有连在一起的红色节点
4、从根节点到每个叶子的路径上的黑色节点数目相等

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

enum COLOR
{
    RED,
    BLACK
};

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

    RBTreeNode<K, V>* _pRight;
    RBTreeNode<K, V>* _pLeft;
    RBTreeNode<K, V>* _pParent;
    K _key;
    V _value;
    COLOR _color;
};

template<class K, class V, class Ref, class Ptr>
class RBIterator
{
    typename typedef RBIterator<K, V, Ref, Ptr> self;
    typename typedef RBTreeNode<K, V> Node;
public:
    RBIterator()
    {}

    RBIterator(const self& it)
    {
        _pNode = it._pNode;
    }

    RBIterator(Node* ptmp)
    {
        _pNode = ptmp;
    }

    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;
    }

    bool operator!=(const self& it)
    {
        return _pNode != it._pNode;
    }

    bool operator==(const self& it)
    {
        return _pNode == it._pNode;
    }

    Ref operator*()
    {
        return _pNode->_key;
    }

    Ptr operator->()
    {
        return &(_pNode->_key);
    }

private:
    void Increment()
    {
        if (_pNode->_pRight)
        {
            Node* ptmp = _pNode->_pRight;
            while (ptmp->_pLeft)
                ptmp = ptmp->_pLeft;
            _pNode = ptmp;
        }
        else
        {
            Node* ptmp = _pNode->_pParent;
            while (_pNode == ptmp->_pRight)
            {
                _pNode = ptmp;
                ptmp = ptmp->_pParent;
            }

            if (_pNode->_pRight != ptmp)
                _pNode = ptmp;
        }
    }

    void Decrement()
    {
        if (_pNode->_color == RED  && _pNode->_pParent->_pParent == _pNode)
            _pNode = _pNode->_pLeft;;
        else if (_pNode->_pLeft)
        {
            Node* ptmp = _pNode->_pLeft;
            while (ptmp->_pRight)
                ptmp = ptmp->_pRight;
            _pNode = ptmp;
        }
        else
        {
            Node* ptmp = _pNode->_pParent;
            while (_pNode == ptmp->_pLeft)
            {
                _pNode = ptmp;
                ptmp = ptmp->_pParent;
            }
            _pNode = ptmp;
        }
    }

private:
    Node* _pNode;
};

template<class K, class V>
class RBTree
{
    typedef RBTreeNode<K, V> Node;
public:
    typename typedef RBIterator<K, V, K&, K*> Itetator;
public:

    RBTree()
        :_pRoot(NULL)
    {
        _pHead = new Node; 
        _pHead->_pLeft = _pHead;
        _pHead->_pRight = _pHead;
        _pHead->_pParent = NULL;
    }

    bool Insert(const K& key, const V& value)
    {
        if (NULL == _pRoot)
        {
            _pRoot = new Node(key, value, BLACK);

            _pRoot->_pParent = _pHead;
            _pHead->_pParent = _pRoot;
            _pHead->_pLeft = _pRoot;
            _pHead->_pRight = _pRoot;
            return true;
        }

        Node* pCur = _pRoot;
        Node* pParent = NULL;
        while (pCur)
        {
            if (key == pCur->_key)
                return false;
            else if (key > pCur->_key)
            {
                pParent = pCur;
                pCur = pCur->_pRight;
            }
            else
            {
                pParent = pCur;
                pCur = pCur->_pLeft;
            }
        }

        pCur = new Node(key, value);
        if (pParent->_key > key)
            pParent->_pLeft = pCur;
        else
            pParent->_pRight = pCur;

        pCur->_pParent = pParent;

        while (pCur && RED == pCur->_color && pParent && RED == pParent->_color)
        {
            Node* pGar = pParent->_pParent;

            if (pParent == pGar->_pLeft)
            {
                Node* pU = pGar->_pRight;

                if (pU && RED == pU->_color)
                {
                    pU->_color = BLACK;
                    pParent->_color = BLACK;
                    pGar->_color = RED;

                    pCur = pGar;
                    pParent = pGar->_pParent;
                }
                else
                {
                    if (pCur == pParent->_pRight)
                    {
                        _RotateL(pParent);

                        std::swap(pParent, pCur);
                    }

                    _RotateR(pGar);

                    pParent->_color = BLACK;
                    pGar->_color = RED;

                    pCur = pParent->_pParent;
                    pParent = pCur->_pParent;
                }
            }
            else
            {
                Node* pU = pGar->_pLeft;

                if (pU && RED == pU->_color)
                {
                    pU->_color = BLACK;
                    pParent->_color = BLACK;
                    pGar->_color = RED;

                    pCur = pGar;
                    pParent = pGar->_pParent;
                }
                else
                {
                    if (pCur == pParent->_pLeft)
                    {
                        _RotateR(pParent);

                        std::swap(pParent, pCur);
                    }

                    _RotateL(pGar);

                    pParent->_color = BLACK;
                    pGar->_color = RED;

                    pCur = pParent->_pParent;
                    pParent = pCur->_pParent;
                }
            }
        }

        _pRoot->_color = BLACK;
        _pHead->_pRight = _GetmaxNode();
        _pHead->_pLeft = _GetminNode();


        return true;
    }

    size_t Size()
    {
        size_t count = 0;
        _Size(_pRoot,count);
        return count;
    }

    Node* Begin()
    {
        return _pHead->_pLeft;
    }

    Node* End()
    {
        return _pHead;
    }

    bool CheckRBTree()
    {
        size_t count = 0;

        _blackCount(_pRoot, count);
        return _CheckRBTree(_pRoot, count, 0);
    }

    void InOrder()
    {
        cout << "InOrder: ";
        _InOrder(_pRoot);
        cout << endl;
    }

private:

    Node* _GetminNode()
    {
        if (NULL == _pRoot)
            return _pRoot;
        Node* pRoot = _pRoot;
        while (pRoot->_pLeft)
            pRoot = pRoot->_pLeft;
        return pRoot;
    }

    Node* _GetmaxNode()
    {   
        if (NULL == _pRoot)
            return _pRoot;
        Node* pRoot = _pRoot;
        while (pRoot->_pRight)
            pRoot = pRoot->_pRight;
        return pRoot;
    }

    void _blackCount(Node* pRoot, size_t &count)
    {
        while (pRoot)
        {
            if (pRoot->_color == BLACK)
                count++;
            pRoot = pRoot->_pLeft;
        }
    }

    void _RotateR(Node* pParent)
    {
        Node* pSubL = pParent->_pLeft;
        Node* pSubLR = pSubL->_pRight;

        pParent->_pLeft = pSubLR;
        if (pSubLR)
            pSubLR->_pParent = pParent;

        pSubL->_pRight = pParent;
        Node* pPParent = pParent->_pParent;
        pParent->_pParent = pSubL;
        pSubL->_pParent = pPParent;
        if (_pHead == pPParent)
        {
            _pRoot = pSubL;
            _pHead->_pParent = _pRoot;
            _pRoot->_pParent = _pHead;
        }
        else
        {
            if (pPParent->_pLeft == pParent)
                pPParent->_pLeft = pSubL;
            else
                pPParent->_pRight = pSubL;
        }
    }

    void _RotateL(Node* pParent)
    {
        Node* pSubR = pParent->_pRight;
        Node* pSubRL = pSubR->_pLeft;

        pParent->_pRight = pSubRL;
        if (pSubRL)
            pSubRL->_pParent = pParent;

        pSubR->_pLeft = pParent;
        Node* pPParent = pParent->_pParent;
        pParent->_pParent = pSubR;
        pSubR->_pParent = pPParent;
        if (_pHead != pPParent)
        {
            if (pPParent->_pLeft == pParent)
                pPParent->_pLeft = pSubR;
            else
                pPParent->_pRight = pSubR;
        }
        else
        {
            _pRoot = pSubR;
            _pHead->_pParent = _pRoot;
            _pRoot->_pParent = _pHead;
        }
    }

    void _InOrder(Node* pRoot)
    {
        if (pRoot)
        {
            _InOrder(pRoot->_pLeft);
            cout << pRoot->_key << ' ';
            _InOrder(pRoot->_pRight);
        }
    }

    bool _CheckRBTree(Node* pRoot, const size_t blackCount, size_t k)
    {
        if (pRoot == NULL)
            return true;

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

        if (pRoot->_color == RED && pRoot->_pParent->_color == RED)
            return false;

        if (pRoot->_pLeft == NULL && pRoot->_pRight == NULL)
        {
            if (blackCount == k)
                return true;
        }

        return _CheckRBTree(pRoot->_pLeft, blackCount, k) && _CheckRBTree(pRoot->_pRight, blackCount, k);
    }

    void _Size(Node* pRoot,size_t& count)
    {
        if (pRoot)
        {
            count++;
            _Size(pRoot->_pLeft, count);
            _Size(pRoot->_pRight, count);
        }
    }

private:
    Node* _pRoot;
    Node* _pHead;
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值