STL-RBTree模拟实现

#pragma once

#include<assert.h>
#include<iostream>
using std::cout;
using std::endl;
using std::cin;
using std::pair;
using std::make_pair;
using std::string;


namespace test
{

    //与库中的RBT差异
    /**
     *
     * 库中还有结点数量 count
     *
     * 库中RBT是带头结点哨兵卫的,头结点的左是中序第一个(最小结点),右节点是中序的最后一个(最大结点),
     * 哨兵卫的parent指向根节点,根节点的parent指向哨兵卫
     *
     * 库中的begin直接取head的left -- 函数:leftmost() //最左结点
     * 库中的end 是head的right -- 不是rightmost,rightmost是最右结点,end是最右结点的下一个
     * 库中的end 需要判断一下,防止只有左子树的歪脖子树时,end == head->right,死循环
     *
     * 和库的区别就是end,库的end能走回到head,我的不能,只能走到空就没了d
     *
     */


    enum Colour { RED, BLACK };

    template<class T> //T是什么,为什么只传T? T为key或pair,T是key或者key-value类型
    struct RBTreeNode
    {
        RBTreeNode* _left;
        RBTreeNode* _right;
        RBTreeNode* _parent;
        T _data; //data是key或pair
        Colour _col;

        RBTreeNode(const T& data)
            : _left(nullptr)
            , _right(nullptr)
            , _parent(nullptr)
            , _data(data)
            , _col(RED)
        {}
    };
    //const_iterator<T,const T&,const T*>
    //iterator<T, T&, T*>

    template<class T, class Ref, typename Ptr>
    struct __RBTree_iterator
    {
        typedef RBTreeNode<T> node;
        node* _node;
        __RBTree_iterator(node* node)
            :_node(node)
        {}

        //因为set迭代器涉及到普通迭代器转换成const迭代器,所以需要写这个拷贝构造用于类型转换,
        //原因1:如果是set把constK传给T.那么const迭代器的Ref就是const constT&,显然不能这么写
        //原因2:const迭代器实例化后为<T,const T&, const T*> ,接收不了<T,T&,T*>的参数 -- 同一个类模板,只要模板参数不同就是不同类型了--多一个const也不行,类模板看<>一不一样
        //综上得知,问题为类型转换问题,即需要单独给const迭代器写一个构造函数,参数为普通迭代器,即可解决类型转换问题
        __RBTree_iterator(const __RBTree_iterator<T,T&,T*>& it) 
            :_node(it._node)
        {}
        //这个构造函数的作用,当迭代器模板被实例化成普通迭代器时,他就是构造函数
        //    被实例化成const迭代器时,他是带参构造函数 --------->那么说,这个函数起到了一石二鸟的作用?
        //const类型的作为返回值的迭代器接收(带参构造)隐式类型(拷贝构造)转换过来的临时变量? --应该也没这么复杂,直接建const临时变量拿来用可能



        //Ref为 T& 或 const T& 
        //Ptr为 T* 或 const T*
        typedef __RBTree_iterator<T, Ref, Ptr> Self;

        Ref operator*()
        {
            return _node->_data;
        }
        Ptr operator->()
        {
            return &(_node->_data);
        }
        bool operator!=(const Self& x)
        {
            return _node != x._node;
        }
        Self& operator++()
        {
            //++逻辑
            /**
             * 如果右子树不为空,则下一个是右子树的最左节点
             *
             * 如果右子树完了,则父亲也完了.
             *
             * 如果我是父亲的左,完了则走父亲
             *
             * 直到没有父亲,结束
             *
             * 方法1:三叉链非递归
             * 方法2:借助栈,非递归
             *
             */
             //if (!_node) //还不知为何不需要判空
             //{
             //    return *this;
             //}

             /**
              * 特性:
              * -- 除了右子树为空,每个结点的下一个是他的右子树走到空的那一个,
              *
              * 1.如果右子树不为空,,每个结点的下一个是他的右子树的最左结点,右子树往左走走到空的那一个,
              * 2.如果右子树为空,则下一个是他所在的左子树的那个结点(祖先),cur往父亲的右倒着走,走到第一个出现的父亲的左,这个父亲就是下一个结点
              * -- 沿着到根的路径往上走,找孩子是左子树的那个祖先
              */
            if (_node->_right)
            {
                node* cur = _node->_right;
                while (cur->_left)
                {
                    cur = cur->_left;
                }
                _node = cur;
            }
            else
            {
                node* cur = _node;
                node* parent = _node->_parent;
                while (parent && parent->_right == cur)
                {
                    cur = parent;
                    parent = parent->_parent;
                }
                _node = parent;
            }

            return *this;
        }
        Self& operator--()
        {
            //和++对称
            if (_node->_left)
            {
                node* cur = _node->_left;
                while (cur->_right)
                {
                    cur = cur->_right;
                }
                _node = cur;
            }
            else
            {
                node* cur = _node;
                node* parent = _node->_parent;
                while (parent && parent->_left == cur)
                {
                    cur = parent;
                    parent = parent->_parent;
                }
                _node = parent;
            }
            return *this;
        }
    };

    //参数K用在find,erase等,虽然K也可以被T取代了,但没必要,K更快
    template<class K, class T, class keyOfT> //库中还有1个compare,先不写了
    class RBTree
    {
    public:
        typedef RBTreeNode<T> node; //T是key或pair
    public:
        typedef __RBTree_iterator<T, T&, T*> iterator;
        typedef __RBTree_iterator<T, const T&, const T*> const_iterator;

        iterator begin()
        {
            node* cur = _root;
            while (cur && cur->_left)//不能走到空
            {
                cur = cur->_left;
            }
            return iterator(cur);//返回中序的第一个结点,最左结点
        }

        iterator end() //end是最一个位置的下一个
        {
            return iterator(nullptr);//暂时可以这么写
        }

        const_iterator begin()const
        {
            node* cur = _root;
            while (cur && cur->_left)
            {
                cur = cur->_left;
            }
            return iterator(cur);
        }

        const_iterator end() const
        {
            return iterator(nullptr);
        }

    private:
        node* _root = nullptr;
    public:
        node* find(const K& key)
        {
            keyOfT kot;//kot是个仿函数,根据不同参数返回不同的参数对象
            node* cur = _root;
            while (cur)
            {
                if (key < kot(cur->_data)) // -------------------------------------------- 只需要重载一个 '<' 或 '>' 就可以比较大小
                {
                    cur = cur->_left;
                }
                else if (kot(cur->_data) < key) // --------------------------------------------只需要重载一个 '<' 或 '>' 就可以比较大小
                {
                    cur = cur->_right;
                }
                else
                {
                    return cur;
                }
            }
            return nullptr;
        }

        pair<iterator, bool> insert(const T& data)
        {
            if (!_root)
            {
                _root = new node(data);
                _root->_col = BLACK;
                return std::make_pair(iterator(_root), true);
            }
            
            keyOfT kot;

            node* cur = _root;
            node* parent = nullptr;
            while (cur)
            {
                if (kot(cur->_data) < kot(data)  ) // --------------------------------------------只需要重载一个 '<' 或 '>' 就可以比较大小
                {
                    parent = cur;
                    cur = cur->_right;
                }
                else if (kot(data) < kot(cur->_data)) // --------------------------------------------只需要重载一个 '<' 或 '>' 就可以比较大小
                {
                    parent = cur;
                    cur = cur->_left;
                }
                else
                {
                    return std::make_pair(iterator(cur), false);
                }
            }
            cur = new node(data);
            if ( kot(parent->_data) < kot(data)) // --------------------------------------------
            {
                parent->_right = cur;
            }
            else
            {
                parent->_left = cur;
            }
            cur->_parent = parent;

            //调整/旋转
            node* newnode = cur;//调整过程cur会发生变化,将cur结点记住 -- 记住原来key的位置
            while (parent && parent->_col == RED)
            {
                node* g = parent->_parent;
                if (parent == g->_right)
                {
                    node* u = g->_left;
                    if (u && u->_col == RED)
                    {
                        g->_col = RED;
                        parent->_col = BLACK;
                        u->_col = BLACK;
                        cur = g;
                        parent = cur->_parent;
                    }
                    else
                    {
                        if (cur == parent->_right)
                        {
                            RotateL(g);
                            parent->_col = BLACK;
                            g->_col = RED;
                        }
                        else
                        {
                            RotateR(parent);
                            RotateL(g);
                            g->_col = RED;
                            cur->_col = BLACK;
                        }
                        break;
                    }

                }
                else
                {
                    node* u = g->_right;
                    if (u && u->_col == RED)
                    {
                        g->_col = RED;
                        parent->_col = BLACK;
                        u->_col = BLACK;
                        cur = g;
                        parent = cur->_parent;
                    }
                    else
                    {
                        if (cur == parent->_left)
                        {
                            RotateR(g);
                            parent->_col = BLACK;
                            g->_col = RED;
                        }
                        else
                        {
                            RotateL(parent);
                            RotateR(g);
                            g->_col = RED;
                            cur->_col = BLACK;
                        }
                        break;
                    }
                }
            }
            _root->_col = BLACK;
            return std::make_pair(iterator(newnode), true);
        }
    public:
        void InOrderTraversal()
        {
            _InOrderTraversal(_root);
        }

        bool isBalanceTree()
        {
            //需要判断3个规则
            //1.根为黑
            if (_root && _root->_col == RED)
            {
                cout << "错误:根是红色" << endl;
                return false;
            }

            //2.不能有连续得红
            //3.黑同
            int benchmark = 0;
            node* cur = _root;
            while (cur)
            {
                if (cur->_col == BLACK)
                {
                    ++benchmark;
                }
                cur = cur->_left;
            }
            return _check(_root, 0, benchmark);
        }

        int Height()
        {
            return _Height(_root);
        }
        ~RBTree()
        {
            Destroy(_root);
        }

    private:
        void Destroy(node*& root)
        {
            if (!root)
            {
                return;
            }
            Destroy(root->_left);
            Destroy(root->_right);
            delete root;
            root = nullptr;
        }

        bool _check(node* root, int blackNum, int benchmark)
        {
            keyOfT kot;
            if (!root) //
            {
                if (blackNum != benchmark)
                {
                    cout << "错误:存在不同路径的黑色结点数量不相同" << endl;
                    return false;
                }
                return true;
            }

            if (root->_col == BLACK)
            {
                ++blackNum;
            }

            if (root->_col == RED && root->_parent->_col == RED)
            {
                cout << kot(root->_data) << " 错误,与父节点同时为红色"; // --------------------------------------------
                return false;
            }

            return _check(root->_left, blackNum, benchmark) && _check(root->_right, blackNum, benchmark);
        }

        int _Height(node* root)
        {
            if (!root)
            {
                return 0;
            }
            int leftH = _Height(root->_left);
            int rightH = _Height(root->_right);

            return leftH > rightH ? leftH + 1 : rightH + 1;
        }

        void _InOrderTraversal(node* root)
        {
            keyOfT kot;
            if (root == nullptr)
            {
                return;
            }
            _InOrderTraversal(root->_left);
            cout << kot(root->_data) << " "; // --------------------------------------------
            _InOrderTraversal(root->_right);
        }

        void RotateL(node* parent)
        {
            node* subR = parent->_right;
            node* subRL = subR->_left;

            parent->_right = subRL;
            if (subRL)
            {
                subRL->_parent = parent;
            }

            node* pparent = parent->_parent;

            subR->_left = parent;
            parent->_parent = subR;

            if (!pparent)
            {
                _root = subR;
                _root->_parent = nullptr;
            }
            else
            {
                if (pparent->_left == parent)
                {
                    pparent->_left = subR;
                }
                else
                {
                    pparent->_right = subR;
                }
                subR->_parent = pparent;
            }
        }

        void RotateR(node* parent)
        {
            node* subL = parent->_left;
            node* subLR = subL->_right;

            parent->_left = subLR;
            if (subLR)
            {
                subLR->_parent = parent;
            }

            node* pparent = parent->_parent;

            subL->_right = parent;
            parent->_parent = subL;


            if (parent == _root)
            {
                _root = subL;
                _root->_parent = nullptr;
            }
            else
            {
                if (pparent->_left == parent)
                {
                    pparent->_left = subL;
                }
                else
                {
                    pparent->_right = subL;
                }
                subL->_parent = pparent;
            }
        }
    };

    

}

 

posted @ 2024-02-27 22:49  HJfjfK  阅读(12)  评论(0编辑  收藏  举报