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 _RBTreeiterator
{
    typedef RBTreeNode<K, V> Node;
    typedef Node* pNode;
    typedef _RBTreeiterator<K, V> Self;

public:
    _RBTreeiterator(pNode pNode = NULL)
        :_pNode(pNode)
    {}

    _RBTreeiterator(const Self& s)
        :_pNode(s._pNode)
    {}

    pair<K,V>& operator*()
    {
        return _pNode->_value;
    }

    pair<K, V>* operator->()
    {
        return &(_pNode->_value);
    }

    Self& operator++()//前置++
    {
        RBTreeIncrement();
        return *this;
    }

    Self operator++(int)//后置++
    {
        Self temp(*this);
        RBTreeIncrement();
        return temp;
    }


    Self& operator--()//前置--
    {
        RBTreeDecrement();
        return *this;
    }

    Self operator--(int)//后置--
    {
        Self temp(*this);
        RBTreeDecrement();
        return temp;
    }

    bool operator==(const Self& s)
    {
        return _pNode == s._pNode;
    }

    bool operator!=(const Self& s)
    {
        return _pNode != s._pNode;
    }

private:

    void RBTreeIncrement()
    {
        if (_pNode->_right)
        {
            _pNode = _pNode->_right;
            while (_pNode->_left)
                _pNode = _pNode->_left;
        }
        else
        {
            pNode pParent = _pNode->_pParent;
            if (pParent->_right == _pNode)
            {
                _pNode = pParent;
                pParent =_pNode->_pParent;
            }
            // 如果树的根节点没有右孩子的情况且迭代器起始位置在根节点
            //if(NULL != _pNode->_pParent->_right)
            if (_pNode->_right != pParent)
            _pNode = pParent;
        }
    }

    void RBTreeDecrement()
    {
        if (_pNode->_pParent->_pParent == _pNode && RED == _pNode->_color)
        {
            _pNode = _pNode->_pRight;
        }
        else if (_pNode->_left)
        {
            _pNode = _pNode->_left;
            while (_pNode->_right)
                _pNode = _pNode->_right;
        }
        else
        {
            pNode pParent = _pNode->_pParent;
            if (pParent->_left == _pNode)
            {
                _pNode = pParent;
                pParent = _pNode->_pParent;
            }

            _pNode = pParent;
        }
    }
private:
    pNode _pNode;
};

template<class K, class V>
class RBTree
{
    typedef RBTreeNode<K, V> Node;
    typedef Node* pNode;
public:
    typedef _RBTreeiterator<K, V> Iterator;

public:
    RBTree()
        :_pHead(new Node)
    {}

    Iterator Begin()
    {
        return Iterator(_pHead->_left);
    }

    Iterator End()
    {
        return Iterator(_pHead->_right);
    }

    pNode& GetRoot()
    {
        return _pHead->_pParent;
    }

    bool InsertUnique(const pair<K,V>& value)
    {  
        pNode& _pRoot = GetRoot();
        //树为空
        if (_pRoot == NULL)
        {
            _pRoot = new Node(value.first, value.second, BLACK);
            _pRoot->_pParent = _pHead;
        }
        else
        {
            //树不为空,找当前结点的插入位置
            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;
        _pHead->_left = MostLeft();
        _pHead->_right = MostRight();
        return true;
    }

    void InOrder()
    {
        _InOrder(GetRoot());
    }

    bool IsRBTree()
    {
        pNode& _pRoot = GetRoot();
        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:

    pNode MostLeft()
    {
        pNode pCur = GetRoot();
        if (pCur == NULL)
            return NULL;
        while (pCur->_left)
        {
            pCur = pCur->_left;
        }
        return pCur;
    }

    pNode MostRight()
    {
        pNode pCur = GetRoot();
        if (pCur == NULL)
            return NULL;
        while (pCur->_right)
        {
            pCur = pCur->_right;
        }
        return pCur;
    }

    //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)
        {
            GetRoot() = 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)
        {
            GetRoot() = pSubL;
            pSubL->_pParent = NULL;
        }
        else
        {
            if (pParent->_left == parent)
                pParent->_left = pSubL;
            else
                pParent->_right = pSubL;
        }       
    }
private:
    pNode _pHead;
};


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

    rbt.InOrder();
    cout << endl;

    if (rbt.IsRBTree())
        cout << "是红黑树" << endl;
    else
        cout << "不是红黑树" << endl;
    RBTree<int, int>::Iterator it = rbt.Begin();
    while (it != rbt.End())
    {
        // operator*()
        cout << (*it).first << " ";
        ++it;
    }
    cout <<(*it).first<< endl;
}
C++中,`std::map`是一个关联容器,它使用红黑树作为底层数据结构,存储键值对。`map`的迭代器提供了遍历和访问这些元素的方式。迭代器的设计实现了两种类型的迭代:正向迭代(从头到尾)和反向迭代(从尾到头)。 1. `map`的迭代器: - **迭代器类型**:`iterator`和`const_iterator`,其中`iterator`用于非常量操作,`const_iterator`用于只读操作。它们都是指向`pair<const Key, T>`的指针,`Key`是映射的键类型,`T`是映射的值类型。 2. **构造**: - 迭代器可以通过`begin()`和`end()`方法创建,分别返回容器的起始和结束迭代器。`cbegin()`和`cend()`提供const版本。 - 对于查找特定键,可以使用`find(key)`返回对应的迭代器,如果找不到则返回`end()`。 3. **操作**: - 迭代器可以用来访问和修改元素,例如`*iterator`获取当前键值对,`*iterator = value`设置键值对,`++iterator`或`--iterator`移动到下一个或前一个元素。 - 通过迭代器,可以进行增删操作,如`container.erase(iterator)`删除当前元素。 4. **迭代模式**: - 通常使用`for (auto it = container.begin(); it != container.end(); ++it)`这样的循环结构进行遍历,`it`在每次迭代都会自动更新指向下一个键值对。 相关问题-- 1. `map`迭代器和容器的关系是什么? 2. 如何使用迭代器进行元素访问和修改? 3. 为什么`map`提供了`begin()`和`end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值