自学内容网 自学内容网

set 与 map底层实现

目录

set与map底层基本介绍​

红黑树的迭代器

operator++

情况一:右不为空

情况二:右为空

operator--

情况一:end()--

情况二:左子树不为空

情况三:右子树不为空

项目代码

RBTree.h

myMap.h

mySet.h


set与map底层基本介绍

红黑树的迭代器

迭代器的好处是可以方便遍历,是数据结构的底层实现与用户透明。如果想要给红黑树增加迭代器,需要考虑以前问题:

begin()与end()

STL明确规定,begin()与end()代表的是一段前闭后开的区间,而对红黑树进行中序遍历后,可以得到一个有序的序列,因此:begin()可以放在红黑树中最小节点(即最左侧节点)的位置,end()放在最大节点(最右侧节点)的下一个位置,关键是最大节点的下一个位置在哪块?能否给成nullptr呢?答案是行不通的,因为对end()位置的迭代器进行--操作,必须要能找最后一个元素,此处就不行,因此最好的方式是将end()放在头结点的位置:

 

operator++

二叉搜索树的中序遍历是升序,如果对某一个数++,那么结果则是中序遍历的下一个数,那么我们如何根据一个值在红黑树当中找到它中序遍历的下一个值呢?

此时我们以局部看整体的思想

情况一:右不为空

情况二:右为空


 

    Self& operator++(){
        if(_node->_right){
            // 右不为空,右子树最左节点就是中序第一个
            Node* leftMost = _node->_right;
            while (leftMost->_left) {
                leftMost = leftMost->_left;
            }
            
            _node = leftMost;
        }else{
            // 右为空
            // 孩子是父亲左的那个祖先
            Node* cur = _node;
            Node* parent = cur->_parent;
            while (parent && cur == parent->_right)
            {
                cur = parent;
                parent = cur->_parent;
            }

                _node = parent;
            }
            return *this;
        }

operator--

情况一:end()--

情况二:左子树不为空

情况三:右子树不为空

    Self& operator--(){
        if(_node == nullptr)//end()
        {
            // --end(),特殊处理,走到中序最后一个节点,整棵树的最右节点
            Node* rightMost = _root;
            while(rightMost && rightMost->_right){
                rightMost = rightMost->_right;
            }
            _node = rightMost;
        }
        else if(_node->_left){
            // 左子树不为空,中序左子树最后一个
            Node* rightMost = _node->_left;
            while(rightMost->_right){
                rightMost = rightMost->_right;
            }
            _node = rightMost;
        }else{
            // 孩子是父亲右的那个祖先
            Node* cur = _node;
            Node* parent = cur->_parent;
            
            while(parent && parent->_left == cur){
                cur = parent;
                parent = parent->_parent;
            }
            _node = parent;
        }
        return *this;
    }
    
};

项目代码

RBTree.h

//
//  RBTree.h
//  红黑树
//
//  Created by 南毅 on 2024/7/22.
//
#include <iostream>
using namespace std;
#include <assert.h>
#include <vector>
#include <time.h>
#include <string.h>

enum Colour{
    RED,
    BLACK
};

template<class T>
struct RBTreeNode
{
    T _data;
    RBTreeNode<T>* _left;
    RBTreeNode<T>* _right;
    RBTreeNode<T>* _parent;
    Colour _col;

    RBTreeNode(const T& data)
        :_left(nullptr)
        , _right(nullptr)
        , _parent(nullptr)
        , _data(data)
        , _col(RED)
    {}
};

template<class T,class Ref, class Ptr>
struct RBTreeIterator {
    typedef RBTreeNode<T> Node;
    typedef RBTreeIterator<T,Ref,Ptr> Self;
    
    Node* _node;
    Node* _root;
    
    RBTreeIterator(Node* node,Node* root)
    :_node(node),
    _root(root)
    {
        
    }
    
    Ref operator*(){
        return _node->_data;
    }
    
    Ptr operator->(){
        return &_node->_data;
    }
    
    
    bool operator!=(const Self& s){
        return _node != s._node;
    }
    
    bool operator==(const Self& s){
        return _node == s._node;
    }
    
    Self& operator++(){
        if(_node->_right){
            // 右不为空,右子树最左节点就是中序第一个
            Node* leftMost = _node->_right;
            while (leftMost->_left) {
                leftMost = leftMost->_left;
            }
            
            _node = leftMost;
        }else{
            // 右为空
            // 孩子是父亲左的那个祖先
            Node* cur = _node;
            Node* parent = cur->_parent;
            while (parent && cur == parent->_right)
            {
                cur = parent;
                parent = cur->_parent;
            }

                _node = parent;
            }
            return *this;
        }
        
    Self& operator--(){
        if(_node == nullptr)//end()
        {
            // --end(),特殊处理,走到中序最后一个节点,整棵树的最右节点
            Node* rightMost = _root;
            while(rightMost && rightMost->_right){
                rightMost = rightMost->_right;
            }
            _node = rightMost;
        }
        else if(_node->_left){
            // 左子树不为空,中序左子树最后一个
            Node* rightMost = _node->_left;
            while(rightMost->_right){
                rightMost = rightMost->_right;
            }
            _node = rightMost;
        }else{
            // 孩子是父亲右的那个祖先
            Node* cur = _node;
            Node* parent = cur->_parent;
            
            while(parent && parent->_left == cur){
                cur = parent;
                parent = parent->_parent;
            }
            _node = parent;
        }
        return *this;
    }
    
};


template<class K, class T, class KeyOfT>
class RBTree
{
public:
    int _rotateNum = 0;
    typedef RBTreeIterator<T,T&,T*> Iterator;
    typedef RBTreeIterator<T,const T&,const T*> ConstIterator;
    
    Iterator Begin(){
        Node* leftMost = _root;
        while(leftMost && leftMost->_left){
            leftMost = leftMost->_left;
        }
        
        return Iterator(leftMost,_root);
    }
    
    
    Iterator End(){
        return Iterator(nullptr,_root);
    }
    
    ConstIterator Begin() const
    {
        Node* leftMost = _root;
        while(leftMost && leftMost->_left){
            leftMost = leftMost->_left;
        }
        
        return ConstIterator(leftMost,_root);
    }
    
    ConstIterator End() const
    {
        return ConstIterator(nullptr,_root);
    }
private:
    typedef RBTreeNode<T> Node;
    Node* _root = nullptr;
    
    void RotateL(Node* parent)
    {
        _rotateNum++;
        Node* subR = parent->_right;
        Node* subRL = subR->_left;

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

        Node* parentParent = parent->_parent;

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

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

            subR->_parent = parentParent;
        }
    }

    void  RotateR(Node* parent)
    {
        _rotateNum++;

        Node* subL = parent->_left;
        Node* subLR = subL->_right;

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

        Node* parentParent = parent->_parent;

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

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

            subL->_parent = parentParent;
        }

    }
    
    void Destroy(Node* root)
    {
        if (root == nullptr)
            return;

        Destroy(root->_left);
        Destroy(root->_right);
        delete root;
    }

    Node* Copy(Node* root)
    {
        if (root == nullptr)
            return nullptr;

        Node* newRoot = new Node(root->_kv);
        newRoot->_left = Copy(root->_left);
        newRoot->_right = Copy(root->_right);

        return newRoot;
    }
    
    bool Check(Node* root, int blackNum, const int refNum)
        {
            if (root == nullptr)
            {
                //cout << blackNum << endl;
                if (refNum != blackNum)
                {
                    cout << "存在黑色节点的数量不相等的路径" << endl;
                    return false;
                }

                return true;
            }

            if (root->_col == RED && root->_parent->_col == RED)
            {
                cout << root->_kv.first << "存在连续的红色节点" << endl;
                return false;
            }

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

            return Check(root->_left, blackNum, refNum)
                && Check(root->_right, blackNum, refNum);
        }

        int _Size(Node* root)
        {
            return root == nullptr ? 0 : _Size(root->_left) + _Size(root->_right) + 1;
        }

        int _Height(Node* root)
        {
            if (root == nullptr)
                return 0;

            int leftHeight = _Height(root->_left);
            int rightHeight = _Height(root->_right);

            return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
        }

        void _InOrder(Node* root)
        {
            if (root == nullptr)
            {
                return;
            }

            _InOrder(root->_left);
            cout << root->_kv.first << ":" << root->_kv.second << endl;
            _InOrder(root->_right);
        }

public:
    RBTree() = default;

    RBTree(const RBTree& t)
    {
        _root = Copy(t._root);
    }

    RBTree& operator=(RBTree t)
    {
        swap(_root, t._root);
        return *this;
    }

    ~RBTree()
    {
        Destroy(_root);
        _root = nullptr;
    }
    
    pair<Iterator,bool> Insert(const T& data){
        // 树为空,插入节点为新根节点
        if(_root == nullptr){
            _root = new Node(data);
            _root->_col = BLACK;
            return make_pair(Iterator(_root,_root), true);
        }
        
        Node* parent = nullptr;
        Node* cur = _root;
        
        KeyOfT kot;
        
        //找到插入位置
        while (cur)
        {
            if (kot(cur->_data) < kot(data))
            {
                parent = cur;
                cur = cur->_right;
            }
            else if (kot(cur->_data) > kot(data))
            {
                parent = cur;
                cur = cur->_left;
            }
            else
            {
                return make_pair(Iterator(cur, _root), false);
            }
        }

        //新增节点。颜色给红色
        cur = new Node(data);
        Node* newnode = cur;
        cur->_col = RED;
        
        if (kot(parent->_data) < kot(data))
        {
            parent->_right = cur;
        }
        else
        {
            parent->_left = cur;
        }
        cur->_parent = parent;

        
        while(parent && parent->_col == RED){
            Node* grandfather = parent->_parent;
            //     g
            //  p     u
            if(parent == grandfather->_left){
                Node* uncle = grandfather->_right;
                if (uncle && uncle->_col == RED) {
                    //情况一 :叔叔存在且为红
                    //变色 + 继续往上处理 p u 变黑 g变红
                    parent->_col = uncle->_col = BLACK;
                    grandfather->_col = RED;
                    
                    cur = grandfather;
                    parent = cur->_parent;
                    
                }
                else{
                    //情况二:叔叔不存在或者存在为黑 --》旋转+变色
                    if(cur == parent->_left){
                        //    g
                        //  p   u
                        //c
                        //单旋:gpc一边高
                        RotateR(grandfather);
                        parent->_col = BLACK;
                        grandfather->_col = RED;
                    }else{
                        //    g
                        //  p   u
                        //    c
                        //双旋:pgc两段高
                        RotateL(parent);
                        RotateR(grandfather);
                        
                        cur->_col = BLACK;
                        grandfather->_col = RED;
                    }
                    
                    break;
                }
            }
            else{
                //    g
                //  u   p
                Node* uncle = grandfather->_left;
                // 叔叔存在且为红,-》变色即可
                if (uncle && uncle->_col == RED)
                {
                    parent->_col = uncle->_col = BLACK;
                    grandfather->_col = RED;
                    
                    // 继续往上处理
                    cur = grandfather;
                    parent = cur->_parent;
                }
                else // 叔叔不存在,或者存在且为黑
                {
                    // 情况二:叔叔不存在或者存在且为黑
                    // 旋转+变色
                    //      g
                    //   u     p
                    //            c
                    if (cur == parent->_right)
                    {
                        RotateL(grandfather);
                        parent->_col = BLACK;
                        grandfather->_col = RED;
                    }
                    else
                    {
                        //        g
                        //   u     p
                        //      c
                        RotateR(parent);
                        RotateL(grandfather);
                        cur->_col = BLACK;
                        grandfather->_col = RED;
                    }
                    break;
                }
                
            }
        }
        _root->_col = BLACK;
        return make_pair(Iterator(newnode, _root), true);

        
    }
    
    void InOrder()
    {
        _InOrder(_root);
        cout << endl;
    }

    int Height()
    {
        return _Height(_root);
    }

    int Size()
    {
        return _Size(_root);
    }

    bool IsBalance()
    {
        if (_root == nullptr)
            return true;

        if (_root->_col == RED)
        {
            return false;
        }
        
        // 参考值
        int refNum = 0;
        Node* cur = _root;
        while (cur)
        {
            if (cur->_col == BLACK)
            {
                ++refNum;
            }

            cur = cur->_left;
        }

        return Check(_root, 0, refNum);
    }

    Iterator Find(const K& key)
    {
        Node* cur = _root;
        while (cur)
        {
            if (cur->_kv.first < key)
            {
                cur = cur->_right;
            }
            else if (cur->_kv.first > key)
            {
                cur = cur->_left;
            }
            else
            {
                return Iterator(cur,_root);
            }
        }

        return End();
    }


};

myMap.h

//
//  myMap.h
//  set和map模拟实现
//
//  Created by 南毅 on 2024/7/23.
//

#include "RBTree.h"

namespace nanyi {
template<class K,class V>
class map{
    struct MapKeyOfT{
        const K& operator()(const pair<K,V>& kv){
            return kv.first;
        }
    };

    
public:
    typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::Iterator iterator;
        typedef typename RBTree<K, pair<const K, V>, MapKeyOfT>::ConstIterator const_iterator;

        iterator begin()
        {
            return _t.Begin();
        }

        iterator end()
        {
            return _t.End();
        }

        const_iterator begin() const
        {
            return _t.Begin();
        }

        const_iterator end() const
        {
            return _t.End();
        }

        pair<iterator, bool> insert(const pair<K, V>& kv)
        {
            return _t.Insert(kv);
        }

        iterator find(const K& key)
        {
            return _t.Find(key);
        }

        V& operator[](const K& key)
        {
            pair<iterator, bool> ret = insert(make_pair(key, V()));
            return ret.first->second;
        }

    private:
        RBTree<K, pair<const K, V>, MapKeyOfT> _t;
    };

    void test_map()
    {
        map<string, string> dict;
        dict.insert({ "sort", "排序" });
        dict.insert({ "left", "左边" });
        dict.insert({ "right", "右边" });

        dict["left"] = "左边,剩余";
        dict["insert"] = "插入";
        dict["string"];

        map<string, string>::iterator it = dict.begin();
        while (it != dict.end())
        {
            // 不能修改first,可以修改second
            //it->first += 'x';
            it->second += 'x';

            cout << it->first << ":" << it->second << endl;
            ++it;
        }
        cout << endl;
    }
};

mySet.h

//
//  mySet.h
//  set和map模拟实现
//
//  Created by 南毅 on 2024/7/23.
//


#include "RBTree.h"

namespace nanyi {
template<class K>
class set{
    struct SetKeyOfT{
        const K& operator()(const K& key){
            return key;
        }
    };
    
    RBTree<K, const K, SetKeyOfT> _t;
public:
    typedef typename RBTree<K, const K, SetKeyOfT>::Iterator iterator;
    typedef typename RBTree<K, const K, SetKeyOfT>::ConstIterator const_iterator;
    
    iterator begin(){
        return _t.Begin();
    }
    
    iterator end(){
        return _t.End();
    }
    
    const_iterator begin() const
    {
        return _t.Begin();
    }

    const_iterator end() const
    {
        return _t.End();
    }
    
    pair<iterator,bool> insert(const K& key){
        return _t.Insert(key);
    }
    
    iterator find(const K& key){
        return _t.Find(key);
    }
    
    void Print(const set<int>& s)
    {
        set<int>::const_iterator it = s.end();
        while (it != s.begin())
        {
            --it;
            //*it += 2;
            cout << *it << " ";
        }
        cout << endl;
    }

};

void Print(const set<int>& s)
{
    set<int>::const_iterator it = s.end();
    while (it != s.begin())
    {
        --it;
        //*it += 2;
        cout << *it << " ";
    }
    cout << endl;
}
void test_set()
{
    set<int> s;
    int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
    for (auto e : a)
    {
        s.insert(e);
    }

    for (auto e : s)
    {
        cout << e << " ";
    }
    cout << endl;

    set<int>::iterator it = s.end();
    while (it != s.begin())
    {
        --it;

        cout << *it << " ";
    }
    cout << endl;

    it = s.begin();
    //*it += 10;
    while (it != s.end())
    {
        cout << *it << " ";
        ++it;
    }
    cout << endl;

    Print(s);
}
}


原文地址:https://blog.csdn.net/2202_75331338/article/details/140658453

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!