目录
- 1. map与set封装红黑树的方式
- 1.1 大概实现思路
- 1.2 红黑树模板抽象
- 1.3 红黑树的迭代器
- 2. 红黑树模板的实现
- 2.1 结点结构的定义
- 2.2 红黑树迭代器的实现
- 2.2.1 迭代器的结构
- 2.2.2 迭代器的方法实现
- 2.3 树结构的定义
- 2.4 红黑树接口实现
- 2.4.1 插入
- 2.4.2 查找
- 2.4.3 迭代器相关
- 3. map与set的自实现
-
1. map与set封装红黑树的方式
1.1 大概实现思路
- STL库中,实现的map与set其底层都为红黑树这种数据结构,在前面的学习中,我们已经简单模拟实现了红黑树。
- 因此,对于map与set的实现无需再去从零开始一一构建,而是可以采用类似于栈与队列这两个容器适配器的形式,直接将红黑树进行封装,调用其的各种方法接口间接实现。
1.2 红黑树模板抽象
- 虽然map与set的底层数据结构都为红黑树,但是,它们也并不是完全相同,map中存储的数据结点为KV类型,而set中存储的数据结点为K类型,所以,两者在接口与使用上也有所不同。
- 可仅仅因此不大的差别就再写一份高度类同的红黑树代码,就不免冗余性过高,由此,我们仿照库中实现的类似方式,将红黑树抽象为模板,通过模板参数来调整细节的方式,来同时适配map与set的需求。
template<class K, class T, class KeyOfT>
1.3 红黑树的迭代器
- 当调用库中的map与set容器时,我们使用相应迭代器遍历其中存储数据,得到的是一串排序好的有序数据。
- 因为map与set的底层本质上为一棵搜索二叉树,这种遍历后得到的数据特点,我们不难知道,迭代器底层实则是在由整颗树最左侧结点做中序遍历,那么,其底层的逻辑究竟应该怎么去实现呢?
2. 红黑树模板的实现
2.1 结点结构的定义
enum colour
{Red,Black
};template<class K, class T>
struct RBTreeNode
{RBTreeNode<K, T>* _left;RBTreeNode<K, T>* _right;RBTreeNode<K, T>* _parent;T _kv;colour _col;RBTreeNode(const T& kv):_left(nullptr),_right(nullptr),_parent(nullptr),_kv(kv),_col(Red){}
};
2.2 红黑树迭代器的实现
2.2.1 迭代器的结构
template<class K, class T, class Ref, class Ptr>
class RBTree_iterator
{typedef RBTreeNode<K, T> RBTNode;
public:RBTree_iterator(RBTNode* node):_node(node){}RBTree_iterator(const RBTree_iterator& it){_node = it._node;}RBTree_iterator operator++(int);RBTree_iterator operator--(int);Ref operator*();Ptr operator->();bool operator==(RBTree_iterator it);bool operator!=(RBTree_iterator it);private:RBTNode* _node;
};
2.2.2 迭代器的方法实现
- 杂项
Ref operator*()
{return _node->_kv;
}
Ptr operator->()
{return &_node->_kv;
}
bool operator==(RBTree_iterator it)
{return _node == it._node;
}bool operator!=(RBTree_iterator it)
{return _node != it._node;
}
- 后置++与–
RBTree_iterator operator++(int)
{RBTree_iterator cp(*this);if (_node->_right){RBTNode* SubLeft = _node->_right;while (SubLeft->_left){SubLeft = SubLeft->_left;}_node = SubLeft;}else{RBTNode* cur = _node;RBTNode* parent = cur->_parent;if (cur == parent->_left){_node = parent;}else{while (parent && cur == parent->_right){cur = parent;parent = cur->_parent;}_node = parent;}}return cp;
}
RBTreeNode_iterator operator--(int)
{RBTree_iterator cp(*this);if (_node->_left){RBTNode* SubRight = _node->_left;while (SubRight->_right){SubRight = SubRight->_right;}_node = SubRight;}else{RBTNode* cur = _node;RBTNode* parent = _node->_parent;while (parent && cur == parent->_left){cur = parent;parent = cur->_parent;}_node = parent;}return cp;
}
2.3 树结构的定义
template<class K, class T, class KeyOfT>
class RBTree
{typedef RBTreeNode<K, T> RBTNode;
public:bool Find(const K& key);pair<iterator, bool> Insert(const T& kv);private:RBTNode* _root = nullptr;KeyOfT con;
}
2.4 红黑树接口实现
2.4.1 插入
pair<iterator, bool> Insert(const T& kv)
{RBTNode* cur = _root;RBTNode* parent = nullptr;while (cur){if (con(kv) < con(cur->_kv)){parent = cur;cur = cur->_left;}else if (con(kv) > con(cur->_kv)){parent = cur;cur = cur->_right;}else{return make_pair(iterator(cur), false);}}RBTNode* newnode = new RBTNode(kv);cur = newnode;if (_root == nullptr){_root = cur;_root->_col = Black;return make_pair(iterator(cur), true);}else{if (con(kv) < con(parent->_kv)){parent->_left = cur;cur->_parent = parent;}else{parent->_right = cur;cur->_parent = parent;}}while (parent){if (parent->_col == Black){break;}else{RBTNode* grandparent = parent->_parent;RBTNode* uncle = grandparent->_left;if (parent == grandparent->_left){uncle = grandparent->_right;}if (uncle && uncle->_col == Red){parent->_col = uncle->_col = Black;grandparent->_col = Red;cur = grandparent;parent = cur->_parent;}else{if (parent == grandparent->_left){if (cur == parent->_left){RotateR(grandparent);parent->_col = Black;grandparent->_col = Red;}else{RotateLR(grandparent);cur->_col = Black;grandparent->_col = Red;}}else{if (cur == parent->_right){RotateL(grandparent);parent->_col = Black;grandparent->_col = Red;}else{RotateRL(grandparent);cur->_col = Black;grandparent->_col = Red;}}break;}}}_root->_col = Black;return make_pair(iterator(newnode), true);
}
2.4.2 查找
bool Find(K key)
{RBTNode* cur = _root;while (cur){if (key < con(cur->_kv)){cur = cur->_left;}else if (key > con(cur->_kv)){cur = cur->_right;}else{return true;}}return false;
}
2.4.3 迭代器相关
typedef RBTree_iterator<K, T, T&, T*> iterator;
typedef RBTree_iterator<K, T, const T&, const T*> const_iterator;iterator begin()
{RBTNode* cur = _root;while (cur->_left){cur = cur->_left;}return cur;
}iterator end()
{return nullptr;
}const iterator cbegin() const
{RBTNode* cur = _root;while (cur->_left){cur = cur->_left;}return cur;
}const iterator cend() const
{return nullptr;
}
3. map与set的自实现
3.1 set封装
template<class K>
class myset
{struct KeyOfT{K operator()(const K& key){return key;}};typedef RBTree_iterator<K, K, K&, K*> iterator;typedef RBTree_iterator<K, K, const K&, const K*> const_iterator;
public:bool Find(K key){return tree.Find(key);}pair<iterator, bool> Insert(K key){return tree.Insert(key);}iterator begin(){return tree.begin();}iterator end(){return tree.end();}const_iterator cbegin() const{return tree.cbegin();}const_iterator cend() const{return tree.cend();}void InOrder(){tree.InOrder();}private:RBTree<K, K, KeyOfT> tree;
};
3.2 map封装
template<class K, class V>
class mymap
{struct KeyOfT{K operator()(const pair<const K, V> kv){return kv.first;}};typedef RBTree_iterator<K, pair<const K, V>, pair<const K, V>&, pair<const K, V>*> iterator;typedef RBTree_iterator<K, pair<const K, V>, const pair<const K, V>&, const pair<const K, V>*> const_iterator;
public:bool Find(K key){return tree.Find(key);}pair<iterator, bool> Insert(const pair<K, V> kv){return tree.Insert(kv);}iterator begin(){return tree.begin();}iterator end(){return tree.end();}const_iterator cbegin() const{return tree.cbegin();}const_iterator cend() const{return tree.cend();}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>, KeyOfT> tree;
};