1.理论分析
先看stl源码中rbtree对set和map的封装

在模拟实现的时候结合map和set的具体需求及stl源码进行分析问题和解决问题

分析KeyOfT存在的原因

对于迭代器本身而言,*,->用于找内容, ++用于向前遍历,--用于回退,==和!=用于迭代;而在用迭代器的具体数据结构比如rbtree需要begin作为开始,end作为结尾,根据需要支持find, insert从而支持[]等操作,同时结合实际使用情况,综合rbtree要封装set和Map,因为set的iterator就是rbtree的const_iterator封装,而insert返回的是普通迭代器,因为如果是const对象不能插入,这时候不支持普通迭代器构造const迭代器,那么迭代器本身就要支持这个构造

每次旋转L,R,LR,RL中间结点也就是新的父结点都是黑色,那即使是成为根节点,也不需要担心染色
blacknum是值传参的好处在于每次递归返回到上层,不会受影响

__TreeIterator的实现和stl中并不完全一样,在迭代的时候nullptr作为end,
但是stl引入了虚拟节点header,header左指针指向最左节点,右指针指向最右节点,parent指针指向root节点,root的parent指针指向header节点,那么可以通过header快速找到最左和最右,但是增删改都要付出代价来维护这一性质,并且在迭代器--的时候,如果左为空,就要向上找最近一个cur是父亲的左孩子,因为是右根左,左结束,根也结束,但如果出现root就是最右节点,这时候root和parent的右指针指向彼此,如果cur是parent的右孩子就一直向上迭代,cur=root,parent=header,此时cur= =parent- >right,则cur=parent=header,parent=cur- >parent=root,依然满足cur==parent- >right,死循环,所以单独做了处理,如果到header就停止


2.代码实现
2.1 测试代码
cpp
#include <utility>
#include <iostream>
#include <string>
using namespace std;
#include "My_Map.h"
#include "My_Set.h"
#include <map>
int main() {
//map测试
diy::map<string, string> mp;
mp.Insert(make_pair("sort", "排序"));
mp.Insert({ "chocolate", "巧克力" });//插入
mp["left"];//插入
mp["right"] = "右边";//插入+赋值
mp["right"] = "测试";//修改
//迭代器
diy::map<string, string>::iterator it = mp.begin();
//auto it = mp.begin();
while (it != mp.end()) {
cout << it->first << ": " << it->second << " ";
++it;
}
cout << endl;
//范围for
for (auto& kv : mp)
cout << kv.first << ": " << kv.second << " ";
cout << endl;
diy::set<int> s;
s.insert(3);
s.insert(5);//插入
s.insert(5);
s.insert(7);
s.insert(4);
diy::set<int>::iterator it = s.begin();
//auto it = s.begin();
while (it != s.end()) {
cout << *it << " ";
++it;
}
cout << endl;
//范围for
for (auto& e : s)
cout << e << " ";
cout << endl;
return 0;
}
2.2 封装set
My_set.h
cpp
#pragma once
#include "BRTree.h"
namespace diy {
template<class K>
class set {
struct SetKeyOfT {
const K& operator()(const K& data) const{
return data;
}
};
typedef BRTree<K, K, SetKeyOfT> rbtree;
public:
typedef typename rbtree::const_iterator iterator;
typedef typename rbtree::const_iterator const_iterator;//set是rbtree封装的,可以使用rbtree的一切组件,如果直接调用__TreeIterator进行实例化就散了
//做了rbtree普通迭代器到const迭代器的转换
/*iterator begin() {
return _t.begin();
}
iterator end() {
return _t.end();
}*/ //可以不写,因为普通对象和const对象都可以调用const,而且只会返回const_iterator
const_iterator begin() const{
return _t.begin();
}
const_iterator end() const{
return _t.end();
}
pair<iterator, bool> insert(const K& key) {
pair<rbtree::iterator,bool> p = _t.Insert(key);
return pair<rbtree::const_iterator, bool>(p.first, p.second);
}
pair<iterator, bool> insert1(const K& key) {
pair<rbtree::iterator, bool> p = _t.Insert(key);
return { p.first, p.second };
}
pair<iterator, bool> insert2(const K& key) {
pair<rbtree::iterator, bool> p = _t.Insert(key);
return make_pair(iterator(p.first), p.second);
}
const_iterator Find(const K& key) const{
return _t.Find(key);
}
private:
rbtree _t;
};
}
2.3 封装map
My_map.h
cpp
#pragma once
#include "BRTree.h"
namespace diy {
template<class K,class V>
class map {
public:
struct MapKeyOfT {
const K& operator()(const pair<const K, V>& data) const{
return data.first;
}
};
typedef BRTree<K, pair<const K,V>, MapKeyOfT> rbtree;
typedef typename BRTree<K, pair<const K, V>, MapKeyOfT>::iterator iterator;
typedef typename rbtree::const_iterator 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();
}
iterator Find(const K& key) {
return _t.Find(key);
}
const_iterator Find(const K& key) const{
return _t.Find(key);
}
pair<iterator, bool> Insert(const pair<const K, V>& data) {
return _t.Insert(data);
}
V& operator[](const K& key) {
pair<iterator, bool> ret = _t.Insert(make_pair(key, V()));
return ret.first->second;
}
private:
rbtree _t;
};
}
2.4 封装rbtree
rbtree.h
cpp
#pragma once
enum color {
RED,
BLACK
};
namespace diy {
template<class T>
struct BRTreeNode {
BRTreeNode<T>* _left;//类名是不等同于类型名的,因为引入模版之后类名+具体参数类型=>类型名
BRTreeNode<T>* _right;
BRTreeNode<T>* _parent;
T _data;
color _col;
BRTreeNode(const T& data)
:_data(data),
_left(nullptr),
_right(nullptr),
_parent(nullptr),
_col(RED)
{}
};
template<class T,class Ptr,class Ref>
struct __TreeIterator {
typedef BRTreeNode<T> Node;
Node* _node;
typedef __TreeIterator<T, T*, T&> iterator;//因为const_iterator可能用到iterator
typedef __TreeIterator<T, Ptr, Ref> Self;
__TreeIterator(Node* node) :_node(node) {};
__TreeIterator(const iterator& it) :_node(it._node) {};//如果是const_iterator就是iterator构造const迭代器,如果是普通迭代器就是拷贝构造
Ref operator*() const{
return _node->_data;
}
Ptr operator->() const{
return &_node->_data;
}
Self& operator++() {//it++ 等价于函数调用it.operator++(),前置++
//左 根 右
//这个地方it一定非空,因为如果是nullptr就和end相等,不会进入
if (_node->_right) {//右子树的最左节点
Node* subleft = _node->_right;
while (subleft->_left)//因为刚开始subleft一定不为空
subleft = subleft->_left;
_node = subleft;
}
else {
Node* cur = _node;//至少cur不为空
Node* parent = cur->_parent;
while (parent && parent->_right == cur) {
cur = parent;
parent = cur->_parent;
}
_node = parent;//要么parent为空,整棵树都遍历完了;要么cur是parent的左子树,该遍历parent了
}
return *this;
}
Self operator++(int) {
Self tmp(_node);
++(*this);
return tmp;
}
Self& operator--() {
if (_node->_left) {
Node* subright = _node->_left;
while (subright->_right)
subright = subright->_right;
_node = subright;
}
else {
Node* cur = _node;
Node* parent = _node->_parent;
while (parent && parent->_left == cur) {
cur = parent;
parent = cur -> _parent;
}
_node = parent;
}
return *this;
}
Self operator--(int) {
Self tmp(*this);
--(*this);
return tmp;
}
bool operator==(const Self& s) const{
return _node==s._node;
}
bool operator!=(const Self& s) const {
return _node != s._node;
}
};
template<class K,class T,class KeyOfT>
class BRTree {
typedef BRTreeNode<T> Node;
Node* _root=nullptr;
public:
typedef __TreeIterator<T, T*, T&> iterator;
typedef __TreeIterator<T, const T*, const T&> const_iterator;
iterator begin() {
Node* cur = _root;
while (cur && cur->_left)
cur = cur->_left;
return iterator(cur);
}
iterator end() {
return iterator(nullptr);
}
const_iterator begin() const{
Node* cur = _root;
while (cur && cur->_left)
cur = cur->_left;
return const_iterator(cur);
}
const_iterator end() const{
return const_iterator(nullptr);
}
iterator Find(const K& k) {
Node* cur = _root;
while (cur) {
if (k > kot(cur->_data))
cur = cur->_right;
else if (k < kot(cur->_data))
cur = cur->_left;
else
return iterator(cur);
}
return iterator(nullptr);
}
const_iterator Find(const K& k) const{
Node* cur = _root;
while (cur) {
if (k > kot(cur->_data))
cur = cur->_right;
else if (k < kot(cur->_data))
cur = cur->_left;
else
return const_iterator(cur);
}
return const_iterator(nullptr);
}
/*BRTree()
:_root(nullptr)
{}*/
KeyOfT kot;
pair<iterator,bool> Insert(const T& data) {
if (_root == nullptr) {
_root = new Node(data);
_root->_col = BLACK;
return make_pair(iterator(_root),true);//make_pair自动推到类型
}
Node* parent = nullptr;
Node* cur = _root;
while (cur) {
if (kot(data) > kot(cur->_data)) {
parent = cur;
cur = cur->_right;
}
else if (kot(data) < kot(cur->_data)) {
parent = cur;
cur = cur->_left;
}
else
return make_pair(iterator(cur),false);
}
//Node* add = Node(data);
/*if (cur == parent->_left)
parent->_left = add;
else if (cur == parent->_right)
parent->_right = add;*/ //其实不太合适,因为有可能左右均为空
//链接父与子
cur = new Node(data);
if (kot(data) > kot(parent->_data))
parent->_right = cur;
else if (kot(data) < kot(parent->_data))
parent->_left = cur;
cur->_parent = parent;
//调整过程中cur可能会改变
Node* newnode = cur;
//调整颜色
while (parent && parent->_col == RED) {
//如果uncle是红色
Node* grandfather = parent->_parent;//用于继续向上迭代
if (parent == grandfather->_left) {
Node* uncle = grandfather->_right;
if (uncle && uncle->_col == RED) {
uncle->_col = parent->_col = BLACK;
grandfather->_col = RED;
cur = grandfather;
parent = cur->_parent;
}
else {//uncle不存在或者为黑
//本质是将一侧的两个红节点通过旋转+染色分散到两端,达到不影响黑色节点数量和不违反红黑树规则的目的
if (cur == parent->_left) {
RotateR(grandfather);
parent->_col = BLACK;//根节点grandfather->parent
grandfather->_col = RED;
}
else{
RotateLR(grandfather);
cur->_col = BLACK;//根节点grandfather->cur
grandfather->_col = RED;
}
break;//不会向上影响
}
}
else if (parent == grandfather->_right) {
Node* uncle = grandfather->_left;
if (uncle && uncle->_col == RED) {
uncle->_col = parent->_col = BLACK;
grandfather->_col = RED;//由黑变红,可能继续向上影响
cur = grandfather;
parent = cur->_parent;
}
else {
if (cur == parent->_right) {
RotateL(grandfather);
parent->_col = BLACK;
grandfather->_col = RED;
}
else if (cur == parent->_left) {
RotateRL(grandfather);
cur->_col = BLACK;
grandfather->_col = RED;
}
break;
}
}
}
_root->_col = BLACK;
return make_pair(iterator(newnode),true);
//每次旋转L,R,LR,RL中间结点也就是新的父结点染色后都是黑色,即使是成为根节点,也不需要担心染色
}
bool RotateR(Node* parent) {
rotateCount++;
Node* cur = parent->_left;
Node* curright = cur->_right;
parent->_left = curright;
if (curright)
curright->_parent = parent;
Node* ppnode = parent->_parent;
parent->_parent = cur;
cur->_right = parent;
if (ppnode == nullptr) {
_root = cur;
//_root->_col = BLACK;
}
else {
if (ppnode->_left == parent)
ppnode->_left = cur;
else
ppnode->_right = cur;
}
cur->_parent = ppnode;
return true;
}
bool RotateL(Node* parent) {
rotateCount++;
Node* cur = parent->_right;
Node* curleft = cur->_left;
parent->_right = curleft;
if(curleft)//注意空指针
curleft->_parent = parent;
Node* ppnode = parent->_parent;
cur->_left = parent;
parent->_parent = cur;
if (ppnode == nullptr)
_root = cur;
else {
if (ppnode->_left == parent)
ppnode->_left = cur;
else
ppnode->_right = cur;
}
cur->_parent = ppnode;
return true;
}
bool RotateLR(Node* parent) {
// g
// p
// c
RotateL(parent->_left);
RotateR(parent);
return true;
}
bool RotateRL(Node* parent) {
// g
// p
// c
RotateR(parent->_right);
RotateL(parent);
return true;
}
void InOrder() {
_InOrder(_root);
}
void _InOrder(Node* root) {//或者是重载
if (root == nullptr)//涉及到传参,递归终止条件,但是如果在类外调用InOrder要么通过GetRoot类成员函数获取或设置为静态成员函数,但一般采用子函数的形式
return;
_InOrder(root->_left);
//cout << root->_data << " ";//封装map时_data是pair<K,V>,封装set时_data是K
_InOrder(root->_right);
}
bool CheckColor(Node* root, int blacknum, int benchmark) {//blacknum是值传参的好处在于每次递归返回到上层,不会受影响
if (root == nullptr)
return blacknum == benchmark;
if (root->_col == BLACK)
blacknum++;
if (root->_col == RED && root->_parent && root->_parent->_col == RED) {
cout << kot(root->_data) << ": 出现连续红色节点" << endl;
return false;
}
return CheckColor(root->_left, blacknum, benchmark) && CheckColor(root->_right, blacknum, benchmark);
}
bool IsBalance() {
return _IsBalance(_root);
}
bool _IsBalance(Node* root) {
if (root == nullptr)
return true;
if (root->_col == RED)
return false;
int benchmark = 0;
Node* cur = root;
while (cur) {
if (cur->_col == BLACK)
benchmark++;
cur = cur->_left;
}
return CheckColor(root, 0, benchmark);
}
int _Height(Node* root) {
if (root == nullptr)
return 0;
int leftHeight = _Height(root->_left);
int rightHeight = _Height(root->_right);
return max(leftHeight, rightHeight) + 1;
}
int Height() {
return _Height(_root);
}
public:
int rotateCount = 0;
};
};