
目录
在前面的博客中我们了解了map和set的基本使用,以及对二叉搜索树、AVL树和红黑树的概念和简单实现有了一定的了解后,对于map和set来说,他们的底层实现都是基于红黑树的。我们知道set是key的模型、map是key/value的模型,那么一棵红黑树是如何实现出map和set的呢?

以上是截取的部分源码结构,我们可以看到set的模板参数是Key,map的模板参数是Key和T;set将Key这个模板参数typedef成了key_type和value_type,map将Key这个模板参数typedef成了key_type、将T这个模板参数typedef成了data_type;
他们同时调用红黑树时,都是用的value_type,对应set的value_type是Key,对应map的value_type是pair
;这意味着红黑树只看传过来的value_type是什么类型的,当上层容器是set的时候,结点当中存储的是键值Key;当上层容器是map的时候,结点当中存储的就是 键值对。
结点结构:
- enum Colour
- {
- RED,
- BLACK
- };
-
- template<class T>
- struct RBTreeNode
- {
- RBTreeNode
* _left; - RBTreeNode
* _right; - RBTreeNode
* _parent; -
- T _data;//存储的数据类型:如果是set,T对应的就是K;如果是map,T对应的就是pair
- Colour _col;
-
- RBTreeNode(const T& data)
- :_left(nullptr)
- , _right(nullptr)
- , _parent(nullptr)
- , _col(RED)
- , _data(data)
- {}
- };
红黑树基本结构:
- template<class k, class T>
- class RBTree
- {
- typedef RBTreeNode
Node; - private:
- Node* _root;
- };
map的基本结构:
- namespace mlg
- {
- template<class k, class v>
- class map
- {
- private:
- RBTree
> _t; - };
- }
set的基本结构:
- namespace mlg
- {
- template<class k>
- class set
- {
- private:
- RBTree
_t; - };
- }
因为红黑树中存储的是T类型,有可能是Key,也有可能是
键值对;那么当我们需要进行结点的键值比较时,应该如何获取结点的键值呢? 当上层容器是set的时候T就是键值Key,直接用T进行比较即可,但当上层容器是map的时候就不行了,此时我们需要从
键值对当中取出键值Key后,再用Key值进行比较。 因此,上层容器map需要向底层红黑树提供一个仿函数,用于获取T当中的键值Key,这样一来,当底层红黑树当中需要比较两个结点的键值时,就可以通过这个仿函数来获取T当中的键值了。
map的仿函数:
- namespace mlg
- {
- template<class k, class v>
- class map
- {
- public:
- struct MapKeyOfT
- {
- const k& operator()(const pair
& kv) - {
- return kv.first;
- }
- };
- private:
- RBTree
, MapKeyOfT> _t; - };
- }
set的仿函数:
- namespace mlg
- {
- template<class k>
- class set
- {
- public:
- struct SetKeyOfT
- {
- const k& operator()(const k& k)
- {
- return k;
- }
- };
- private:
- RBTree
_t; - };
- }
红黑树的正向迭代器实际上就是对结点指针进行了封装,因此在正向迭代器当中实际上就只有一个成员变量,那就是正向迭代器所封装结点的指针。
- template<class T, class Ref, class Ptr>
- struct RBTreeIterator
- {
- typedef RBTreeNode
Node;//结点的类型 - typedef RBTreeIterator
Self;//正向迭代器的类型 - Node* _node;//正向迭代器所封装结点的指针
-
- RBTreeIterator(Node* node)//根据所给结点指针构造一个正向迭代器
- :_node(node)
- {}
-
- Ref operator*()
- {
- return _node->_data;//返回结点数据的引用
- }
-
- Ptr operator->()
- {
- return &_node->_data;//返回结点数据的指针
- }
-
- //前置++
- /*
- 如果当前结点的右子树不为空,则++操作后应该找到其右子树当中的最左结点。
- 如果当前结点的右子树为空,则++操作后应该在该结点的祖先结点中,找到孩子不在父亲右的祖先。
- */
- Self& operator++()
- {
- if (_node->_right)//结点的右子树不为空
- {
- Node* min = _node->_right;
- while (min->_left)
- {
- min = min->_left;
- }
- _node = min;
- }
- else //结点的右子树为空
- {
- Node* cur = _node;
- Node* parent = cur->_parent;
- while (parent && cur == parent->_right)
- {
- cur = cur->_parent;
- parent = parent->_parent;
- }
- _node = parent;
- }
- return *this;
- }
-
- //前置--
- /*
- 如果当前结点的左子树不为空,则--操作后应该找到其左子树当中的最右结点。
- 如果当前结点的左子树为空,则--操作后应该在该结点的祖先结点中,找到孩子不在父亲左的祖先。
- */
- Self& operator--()
- {
- if (_node->_left)
- {
- Node* max = _node->_left;
- while (max->_right)
- {
- max = max->_right;
- }
- _node = max;
- }
- else
- {
- Node* cur = _node;
- Node* parent = cur->_parent;
- while (parent && cur == parent->_left)
- {
- cur = parent;
- parent = parent->_parent;
- }
- _node = parent;
- }
- return *this;
- }
-
- //判断两个正向迭代器是否不同
- bool operator!=(const Self& s)const
- {
- return _node != s._node;
- }
-
- //判断两个正向迭代器是否相同
- bool operator==(const Self& s)const
- {
- return _node == s._node;
- }
- };
- #pragma once
- #include
- #include
- using namespace std;
-
- enum Colour
- {
- RED,
- BLACK
- };
-
- template<class T>
- struct RBTreeNode
- {
- RBTreeNode
* _left; - RBTreeNode
* _right; - RBTreeNode
* _parent; -
- T _data;
- Colour _col;
-
- RBTreeNode(const T& data)
- :_left(nullptr)
- , _right(nullptr)
- , _parent(nullptr)
- , _col(RED)
- , _data(data)
- {}
- };
-
- template<class T, class Ref, class Ptr>
- struct RBTreeIterator
- {
- typedef RBTreeNode
Node; - typedef RBTreeIterator
Self; - Node* _node;
-
- RBTreeIterator(Node* node)
- :_node(node)
- {}
-
- Ref operator*()
- {
- return _node->_data;
- }
-
- Ptr operator->()
- {
- return &_node->_data;
- }
- //前置++
- Self& operator++()
- {
- if (_node->_right)
- {
- Node* min = _node->_right;
- while (min->_left)
- {
- min = min->_left;
- }
- _node = min;
- }
- else
- {
- Node* cur = _node;
- Node* parent = cur->_parent;
- while (parent && cur == parent->_right)
- {
- cur = cur->_parent;
- parent = parent->_parent;
- }
- _node = parent;
- }
- return *this;
- }
- //前置--
- Self& operator--()
- {
- if (_node->_left)
- {
- Node* max = _node->_left;
- while (max->_right)
- {
- max = max->_right;
- }
- _node = max;
- }
- else
- {
- Node* cur = _node;
- Node* parent = cur->_parent;
- while (parent && cur == parent->_left)
- {
- cur = parent;
- parent = parent->_parent;
- }
- _node = parent;
- }
- return *this;
- }
-
- bool operator!=(const Self& s)const
- {
- return _node != s._node;
- }
- bool operator==(const Self& s)const
- {
- return _node == s._node;
- }
- };
-
-
- //set RBTree
- //map RBTree
> - template<class k, class T, class keyofT>
- class RBTree
- {
- typedef RBTreeNode
Node; - public:
- typedef RBTreeIterator
iterator; - typedef RBTreeIterator
const T&, const T*> const_iterator; -
- iterator begin()
- {
- Node* min = _root;
- while (min && min->_left)
- {
- min = min->_left;
- }
- return iterator(min);
- }
-
- iterator end()
- {
- return iterator(nullptr);
- }
-
- RBTree()
- :_root(nullptr)
- {}
-
- RBTree(const RBTree
& t) - {
- _root = Copy(t._root);
- }
- Node* Copy(Node* root)
- {
- if (root == nullptr)
- {
- return nullptr;
- }
- Node* newRoot = new Node(root->_data);
- newRoot->_col = root->_col;
-
- newRoot->_left = Copy(root->_left);
- newRoot->_right = Copy(root->_right);
- if (newRoot->_left)
- {
- newRoot->_left->_parent = newRoot;
- }
- if (newRoot->_right)
- {
- newRoot->_right->_parent = newRoot;
- }
- return newRoot;
- }
-
- RBTree
& operator=(RBTree t) - {
- swap(_root, t._root);
- return *this;
- }
-
- ~RBTree()
- {
- Destroy(_root);
- _root = nullptr;
- }
-
- void Destroy(Node* root)
- {
- if (root == nullptr)
- {
- return;
- }
- Destroy(root->_left);
- Destroy(root->_right);
- delete root;
- }
- iterator Find(const k& key)
- {
- Node* cur = _root;
- keyofT kot;
- while (cur)
- {
- if (kot(cur->_data) < key)
- {
- cur = cur->_right;
- }
- else if (kot(cur->_data) > key)
- {
- cur = cur->_left;
- }
- else
- {
- return iterator(cur);
- }
- }
- return end();
- }
-
- pair
bool > Insert(const T& data) - {
- if (_root == nullptr)
- {
- _root = new Node(data);
- _root->_col = BLACK;
- return make_pair(iterator(_root), true);
- }
-
- keyofT kot;
-
- Node* parent = nullptr;
- Node* cur = _root;
- 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), false);
- }
- }
-
- cur = new Node(data);
- Node* newnode = cur;
- cur->_col = RED; // 新增节点
- if (kot(parent->_data) < kot(data))
- {
- parent->_right = cur;
- cur->_parent = parent;
- }
- else
- {
- parent->_left = cur;
- cur->_parent = parent;
- }
-
- // 控制平衡
- while (parent && parent->_col == RED)
- {
- Node* grandfather = parent->_parent;
- if (parent == grandfather->_left)
- {
- Node* uncle = grandfather->_right;
- // 1、uncle存在且为红
- if (uncle && uncle->_col == RED)
- {
- // 变色+继续向上处理
- parent->_col = uncle->_col = BLACK;
- grandfather->_col = RED;
-
- cur = grandfather;
- parent = cur->_parent;
- }
- else // 2 + 3、uncle不存在/ 存在且为黑
- {
- if (cur == parent->_left)
- {
- // 单旋
- RotateR(grandfather);
- parent->_col = BLACK;
- grandfather->_col = RED;
- }
- else
- {
- // 双旋
- RotateL(parent);
- RotateR(grandfather);
- cur->_col = BLACK;
- grandfather->_col = RED;
- }
- break;
- }
- }
- else // parent == grandfather->_right
- {
- Node* uncle = grandfather->_left;
- if (uncle && uncle->_col == RED)
- {
- // 变色+继续向上处理
- parent->_col = uncle->_col = BLACK;
- grandfather->_col = RED;
-
- cur = grandfather;
- parent = cur->_parent;
- }
- else // 2 + 3、uncle不存在/ 存在且为黑
- {
- if (cur == parent->_right)
- {
- RotateL(grandfather);
- parent->_col = BLACK;
- grandfather->_col = RED;
- }
- else
- {
- RotateR(parent);
- RotateL(grandfather);
- cur->_col = BLACK;
- grandfather->_col = RED;
- }
-
- break;
- }
- }
- }
- _root->_col = BLACK;
- return make_pair(iterator(newnode), true);
- }
-
- //左单选
- void RotateL(Node* parent)
- {
- 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 (parent == _root)//这里表明原来是根
- {
- _root = subR;
- subR->_parent = nullptr;
- }
- else
- {
- if (parentParent->_left == parent)
- {
- parentParent->_left = subR;
- }
- else
- {
- parentParent->_right = subR;
- }
- subR->_parent = parentParent;
- }
- }
-
- //由单旋
- void RotateR(Node* parent)
- {
- 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 (parent == _root)//这里表明原来是根
- {
- _root = subL;
- _root->_parent = nullptr;
- }
- else
- {
- if (parentParent->_left == parent)
- {
- parentParent->_left = subL;
- }
- else
- {
- parentParent->_right = subL;
- }
- subL->_parent = parentParent;
- }
- }
-
- void InOrder()
- {
- _InOrder(_root);
- }
- void _InOrder(Node* root)
- {
- if (root == nullptr)
- {
- return;
- }
- _InOrder(root->_left);
- cout << root->_kv.first << ":" << root->_kv.second << endl;
- _InOrder(root->_right);
- }
- private:
- Node* _root;
- };
- #include "RBTree.h"
- namespace mlg
- {
- template<class k, class v>
- class map
- {
- public:
- struct MapKeyOfT
- {
- const k& operator()(const pair
& kv) - {
- return kv.first;
- }
- };
- typedef typename RBTree
, MapKeyOfT>::iterator iterator; -
- iterator begin()
- {
- return _t.begin();
- }
-
- iterator end()
- {
- return _t.end();
- }
-
- pair
bool > insert(const pair& kv) - {
- return _t.Insert(kv);
- }
-
- iterator find(const k& key)
- {
- return _t.Find(key);
- }
- v& operator[](const k& key)
- {
- auto ret = _t.Insert(make_pair(key, v()));
- return ret.first->second;
- }
- private:
- RBTree
, MapKeyOfT> _t; - };
- }
- #include "RBTree.h"
- namespace mlg
- {
- template<class k>
- class set
- {
- public:
- struct SetKeyOfT
- {
- const k& operator()(const k& k)
- {
- return k;
- }
- };
-
- typedef typename RBTree
::iterator iterator; -
- iterator begin()
- {
- return _t.begin();
- }
-
- iterator end()
- {
- return _t.end();
- }
-
- pair
bool > insert(const k& key) - {
- return _t.Insert(key);
- }
-
- iterator find(const k& key)
- {
- return _t.Find(key);
- }
- private:
- RBTree
_t; - };
- }