主要是对模板的理解
首先对map封装
map是一种KV模型,在传参时,需要用pair将两个参数耦合,创建了一个类型,而set只需要传一个key值,所有需要统一接口。
原来传参的模板为
map--> RBTree<K,V,OfKV> // 这里的OfKV也是用于统一接口
set-->RBTree<K,OfKV>
这样他们的接口不统一
统一的模板
在map类中 :RBTree<K, pair<K, V>, OfKV> _map; // 由于要统一,K只用来比较大小,pair<K,V>获取键值和映射值
在set类中:RBTree<K, K, OfKV> _set;
// 这样就构成了统一的模板个数
// 再将pair<K,V> 和 K 统一处理为KV类型
RBTree的模板:template<K,KV,OfKV>
节点结构体
template<class KV>
struct RBTreeNode
{
RBTreeNode* _left;
RBTreeNode* _right;
RBTreeNode* _parent;
KV _kv;
Color _color;
RBTreeNode(const KV& kv)
:_left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _color(RED)
,_kv(kv)
{
}
};
通过一个_kv就完成了赋值,对于map类型,KV就是pair<K,V>,key就是_kv的first,value就是_kv的second。对于set类型,KV就是K,_kv就代表key。
那么RBTree在不知道类型的情况下,是如何获取key进行比较的呢?
这时候,OfKV就发挥了作用,OfKV实际上是一个仿函数,在RBTree类中实例化。调用存在set类和map类中各自的函数获取key值。
用结构体创建一个新的类型,再将该类型作为模板传到RBTree类中实例化,调用函数获取键值。
struct MakeKeyOfT // 用仿函数,获取键值,为了与map一致,也写一个仿函数,形成统一接口
{
const K& operator()(const K& k)
{
return k;
}
};
MakeKeyOfT koft; //实例化
struct MakeKeyOfT // 用仿函数,获取键值
{
const K& operator()(const pair<K, V>& kv)
{
return kv.first;
}
};
接下来就是迭代器
迭代器是由一个红黑树节点和一些成员函数构成,迭代器的目的就是遍历,获取数据,而获取的数据都是KV类型的,因为_node的成员变量就是kv。
模板也只需要template<class KV>
template<class KV>
class RBTiterator
{
typedef RBTreeNode<KV> RBTreeNode;
typedef RBTiterator<KV> iterator;
public:
RBTreeNode* _node;
RBTiterator(RBTreeNode* node=nullptr)
:_node(node)
{ }
KV& operator*()
{
return _node->_kv;
}
KV* operator->()
{
return &_node->_kv;
}
iterator& operator++() // 前置++
{
if (_node->_right) // 右子树非空,找右子树最左节点
{
RBTreeNode* subR = _node->_right;
while(subR->_left)
{
subR = subR->_left;
}
_node = subR;
}
else // 右子树为空
{
// 往回找祖先节点
RBTreeNode* parent = _node->_parent;
while (parent && _node == parent->_right)
{
_node = parent;
parent = parent->_parent;
}
_node = parent;
}
return *this;
}
bool operator!=(iterator it)
{
return _node != it._node;
}
};
map的operator[]重载函数
V& operator[](const K& k)
{
pair<iterator, bool> ret = _map.Insert(make_pair(k, V())); // V() 默认为0或空
{
return ret.first->second;
}
}
pair<iterator,bool> Insert(const pair<K,V>& kv)
{
return _map.Insert(kv);
}
源码
// .h
#pragma once
#include<iostream>
#include<utility>
using namespace std;
enum Color
{
RED,
BLACK
};
template<class KV>
struct RBTreeNode
{
RBTreeNode* _left;
RBTreeNode* _right;
RBTreeNode* _parent;
KV _kv;
Color _color;
RBTreeNode(const KV& kv)
:_left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _color(RED)
,_kv(kv)
{
}
};
template<class KV>
class RBTiterator
{
typedef RBTreeNode<KV> RBTreeNode;
typedef RBTiterator<KV> iterator;
public:
RBTreeNode* _node;
RBTiterator(RBTreeNode* node=nullptr)
:_node(node)
{ }
KV& operator*()
{
return _node->_kv;
}
KV* operator->()
{
return &_node->_kv;
}
iterator& operator++() // 前置++
{
if (_node->_right) // 右子树非空,找右子树最左节点
{
RBTreeNode* subR = _node->_right;
while(subR->_left)
{
subR = subR->_left;
}
_node = subR;
}
else // 右子树为空
{
// 往回找祖先节点
RBTreeNode* parent = _node->_parent;
while (parent && _node == parent->_right)
{
_node = parent;
parent = parent->_parent;
}
_node = parent;
}
return *this;
}
bool operator!=(iterator it)
{
return _node != it._node;
}
};
template<class K, class KV, class KOfT>
class RBTree
{
public:
typedef RBTreeNode<KV> RBTreeNode;
typedef RBTiterator<KV> iterator; // KV可以是K也可以是K V的pair<K,V>
public:
RBTree()
:_node(nullptr)
{
}
iterator begin()
{
RBTreeNode* subL = _node;
while (subL->_left)
{
subL = subL->_left;
}
return iterator(subL);
}
iterator end()
{
return iterator(nullptr);
}
pair<iterator,bool> Insert(const KV& kv)
{
if (_node == nullptr)
{
_node = new RBTreeNode(kv);
_node->_color = BLACK;
return make_pair(iterator(_node), true);
}
KOfT koft; // 用于获取键值
const K& key = koft(kv);
RBTreeNode* cur = _node;
RBTreeNode* parent = _node;
while (cur)
{
if (key < koft(cur->_kv))
{
parent = cur;
cur = cur->_left;
}
else if (key > koft(cur->_kv))
{
parent = cur;
cur = cur->_right;
}
else
{
return make_pair(iterator(cur), false);
}
}
if (key < koft(parent->_kv))
{
parent->_left = new RBTreeNode(kv);
parent->_left->_parent = parent;
parent->_left->_color = RED;
cur = parent->_left;
}
if (key > koft(parent->_kv))
{
parent->_right = new RBTreeNode(kv);
parent->_right->_parent = parent;
parent->_right->_color = RED;
cur = parent->_right;
}
RBTreeNode* newinsert = cur; // 记录插入的节点,以便返回
while (cur != _node && parent != _node)
{
if (parent->_color == BLACK)
{
return make_pair(iterator(newinsert), true);
}
else // paretn->_color==RED
{
if (parent == parent->_parent->_left) // cur 和 parent位于 g左边的情况
{
RBTreeNode* uncle = parent->_parent->_right;
if (uncle == nullptr && cur == parent->_left) // 开始即结束 直接变形
{
RBTreeNode* Grandp = parent->_parent;
RotateR(parent->_parent);
parent->_color = BLACK;
Grandp->_color = RED;
return make_pair(iterator(newinsert), true);
}
else if (uncle == nullptr && cur == parent->_right)
{
RBTreeNode* Grandp = parent->_parent;
RotateL(parent);
RotateR(Grandp);
Grandp->_color = RED;
cur->_color = BLACK;
return make_pair(iterator(newinsert), true);
}
else if (uncle->_color == RED) //向上调 // cur 位于 parent的左边 右边都行
{
parent->_color = BLACK;
uncle->_color = BLACK;
if (parent->_parent != _node)
{
parent->_parent->_color = RED;
}
cur = parent->_parent;
parent = cur->_parent;
}
else if (uncle->_color == BLACK && cur == parent->_left) // 开始旋转
{
RBTreeNode* Grandp = parent->_parent;
RotateR(parent->_parent);
parent->_color = BLACK;
Grandp->_color = RED;
return make_pair(iterator(newinsert), true);
}
else if (uncle->_color == BLACK && cur == parent->_right)
{
RBTreeNode* Grandp = parent->_parent;
RotateL(parent);
RotateR(Grandp);
Grandp->_color = RED;
cur->_color = BLACK;
return make_pair(iterator(newinsert), true);
}
}
else // parent==paretn->_parent->_right
{
RBTreeNode* uncle = parent->_parent->_left;
if (uncle == nullptr && cur == parent->_right)
{
RBTreeNode* Grandp = parent->_parent;
RotateL(parent->_parent);
Grandp->_color = RED;
parent->_color = BLACK;
return make_pair(iterator(newinsert), true);
}
else if (uncle == nullptr && cur == parent->_left)
{
RBTreeNode* Grandp = parent->_parent;
RotateR(parent);
RotateL(Grandp);
cur->_color = BLACK;
Grandp->_color = RED;
return make_pair(iterator(newinsert), true);
}
else if (uncle->_color == RED)
{
parent->_color = BLACK;
uncle->_color = BLACK;
if (parent->_parent != _node)
{
parent->_parent->_color = RED;
}
cur = parent->_parent;
parent = cur->_parent;
}
else if (uncle->_color == BLACK && cur == parent->_left)
{
RBTreeNode* Grandp = parent->_parent;
RotateL(parent->_parent);
parent->_color = BLACK;
Grandp->_color = RED;
return make_pair(iterator(newinsert), true);
}
else if (uncle->_color == BLACK && cur == parent->_right)
{
RBTreeNode* Grandp = parent->_parent;
RotateR(parent);
RotateL(Grandp);
Grandp->_color = RED;
cur->_color = BLACK;
return make_pair(iterator(newinsert), true);
}
}
}
}
}
void RotateL(RBTreeNode* root)
{
if (root == nullptr)
{
return;
}
RBTreeNode* rootR = root->_right;
root->_right = rootR->_left;
if (rootR->_left)
{
rootR->_left->_parent = root;
}
rootR->_left = root;
RBTreeNode* g = root->_parent;
root->_parent = rootR;
if (root == _node)
{
_node = rootR;
rootR->_parent = nullptr;
}
else
{
rootR->_parent = g;
if (root == g->_left)
{
g->_left = rootR;
}
else
{
g->_right = rootR;
}
}
}
void RotateR(RBTreeNode* root)
{
if (root == nullptr)
{
return;
}
RBTreeNode* rootL = root->_left;
root->_left = rootL->_right;
if (rootL->_right)
{
rootL->_right->_parent = root;
}
rootL->_right = root;
RBTreeNode* g = root->_parent;
root->_parent = rootL;
if (root == _node)
{
_node = rootL;
rootL->_parent = nullptr;
}
else
{
rootL->_parent = g;
if (root == g->_left)
{
g->_left = rootL;
}
else
{
g->_right = rootL;
}
}
}
RBTreeNode* GetNode()
{
return _node;
}
private:
RBTreeNode* _node;
};
map.h
#pragma once
#include<iostream>
using namespace std;
#include".h"
template<class K, class V>
class map
{
public:
struct MakeKeyOfT // 用仿函数,获取键值
{
const K& operator()(const pair<K, V>& kv)
{
return kv.first;
}
};
struct MakeKeyOfT2
{
const V& operator()(const pair<K, V>& kv)
{
return kv.second;
}
};
typedef typename RBTree<K, pair<K,V>, MakeKeyOfT>::iterator iterator; // 因为iterator 在RBTree中也是引用的,需要加typename
pair<iterator,bool> Insert(const K& key,const V& value)
{
return _map.Insert(make_pair(key,value));
}
iterator begin()
{
return _map.begin();
}
iterator end()
{
return _map.end();
}
MakeKeyOfT koft;
MakeKeyOfT2 koft2;
void _InOrder(RBTreeNode<pair<K,V>>* root)
{
if (root == nullptr)
{
return;
}
_InOrder(root->_left);
cout << koft(root->_kv) << " " << koft2(root->_kv)<< endl;
_InOrder(root->_right);
}
void InOrder()
{
_InOrder(_map.GetNode());
}
V& operator[](const K& k)
{
pair<iterator, bool> ret = _map.Insert(make_pair(k, V())); // V() 默认为0或空
{
return ret.first->second;
}
}
private:
RBTree<K, pair<K, V>, MakeKeyOfT> _map; // 由于要统一,K只用来比较大小,pair<K,V>获取键值和映射值
};
set.h
#pragma once
#include<iostream>
using namespace std;
#include".h"
template<class K>
class set
{
public:
struct MakeKeyOfT // 用仿函数,获取键值,为了与map一致,也写一个仿函数,形成统一接口
{
const K& operator()(const K& k)
{
return k;
}
};
MakeKeyOfT koft;
typedef typename RBTree<K, K, MakeKeyOfT>::iterator iterator;
pair<iterator,bool> Insert(const K& k)
{
return _set.Insert(k);
}
void _InOrder(RBTreeNode<K>* root)
{
if (root == nullptr)
{
return;
}
_InOrder(root->_left);
cout << koft(root->_kv)<< endl;
_InOrder(root->_right);
}
void InOrder()
{
_InOrder(_set.GetNode());
}
iterator beign()
{
return _set.begin();
}
iterator end()
{
return _set.end();
}
private:
RBTree<K, K, MakeKeyOfT> _set; // 由于要统一,K只用来比较大小,pair<K,V>获取键值和映射值
};