本节把红黑树封装到set与map容器中去主要就是迭代器的自增自减,封装的大部分内容都展示到最后代码中了
1. 红黑树的改造
因为set容器只有关键码值,map容器中不仅要存关键码值,还要存关键码值对应的数据。但是红黑树只有一颗,我们如何让一颗树适配两种存储模式。
答案就是给红黑树两个模板参数,无论是set还是map第一个模板参数都用来表示关键码值,第二个模板参数,如果是set就存关键码值,如果是map就存pair数据。红黑树节点就只给一个模板参数只用来存储数据,也就是树的第二个模板参数。
如此修改就可以做到set和map同用一颗红黑树了。
但是因为我们之前红黑树是按map的方案写的,也就是说,插入中对比key值大小从而判断向左还是向右走的逻辑我们都是用 ->_kv.first 的方式访问key值的,但是明显set没办法这么操作。
因此我们再在set和map容器中添加一个仿函数,用来取节点的关键码值
之后在树中比较关键码值就可以直接用这个KeyofT生成的仿函数来取关键码。
那树的第一个模板参数的用途就是给搜索和删除,在查找节点时,我们只需要对比关键码值就可以了。
2. 红黑树的迭代器
关于构建迭代器的思路,我们不在容器上构建迭代器,而是直接在容器的底层,也就是红黑树中构建底层的迭代器,容器的迭代器就封装底层就好了。
我们将迭代器的框架构建好,并在红黑树中实现好begin和end。这个end可以直接给空指针,因为树结束的下一个节点就是空指针。begin就是中序的第一个,也就是最左节点。
下一步,我们将begin和end再封装进set和map容器中去。
然后我们该实现迭代器的自增和自减了
2.1 operator++()
迭代器的下一位就是中序遍历的下一位,中序遍历的顺序是 左-中-右 那么此时给到中节点了,下面分为两种情况:右树存在或右树不存在。
当右树存在时右子树的最左节点就是中序的下一位。
当右树不存在时,说明以该节点为根的子树已经访问完了,然后回到父亲。那如何判断父节点是否也访问完了,就需要看父节点与该节点是不是在同侧,或者说如果该节点是父节点的右孩子,说明父节点也访问完了,只有该节点是父节点的左孩子时说明父节点还未访问。如果父节点为空,说明整棵树已经遍历完了。
2.2 operator--()
自减的逻辑与自增完全相反,或者说自减的遍历顺序是 右-中-左。
但是我们这里要给end()迭代器做一下特殊处理,因为end()迭代器的上一位在逻辑上是中序遍历的最后一位,但是我们的end()迭代器给的是个空指针,它无法像其他正常节点那样操作。我们的特殊操作就是判断当下的迭代器是否是end(),如果是就直接来到中序遍历的最后一位,也就是最右节点。
但是这么做特殊处理也有弊端,就是当_root被旋转改变了之后迭代器就失效了。因此在库中,root上面还有一个head节点用来维护树,其中存储了root节点,最左节点和最右节点的信息,这样就不会出现迭代器失效的问题了,同时end()迭代器可以直接给head节点而不用给空了,并且每次找最左节点和最右节点时也非常方便。
3. 完整代码
RBTree.h
//节点的颜色
enum color{RED,BLACK};
//红黑树节点的定义
template<class T>
struct RBTNode
{
RBTNode(const T& data, color color = RED)
: _data(data)
, _left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _col(color)
{}
T _data;
RBTNode<T>* _left;
RBTNode<T>* _right;
RBTNode<T>* _parent;
color _col; //节点颜色
};
//红黑树的迭代器
template<class T, class Ref, class Ptr>
struct RBTIterator
{
typedef RBTNode<T> Node;
typedef RBTIterator<T, Ref, Ptr> Self;
Node* _node;
Node* _root;
//构造
RBTIterator(Node* node, Node* root)
:_node(node)
,_root(root)
{}
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 = parent->_parent;
}
_node = parent;
}
return *this;
}
Self& operator--()
{
if (_node == nullptr)//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 && cur == parent->_left)
{
cur = parent;
parent = parent->_parent;
}
_node = parent;
}
return *this;
}
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;
}
};
template<class K, class T, class KeyOfT >
class RBTree
{
typedef RBTNode<T> Node;
public:
typedef RBTIterator<T,T&,T*> Iterator;
typedef RBTIterator<T, const T&, const T*> Const_Iterator;
Iterator Begin()
{
Node* leftmost = _root;
while (leftmost && leftmost->_left)
{
leftmost = leftmost->_left;
}
return Iterator(leftmost, _root);
}
Iterator End()
{
return Iterator(nullptr, _root);
}
Const_Iterator Begin() const
{
Node* leftmost = _root;
while (leftmost && leftmost->_left)
{
leftmost = leftmost->_left;
}
return Const_Iterator(leftmost, _root);
}
Const_Iterator End() const
{
return Const_Iterator(nullptr, _root);
}
//构造
RBTree() = default;
//拷贝构造
RBTree(const RBTree<K, T, KeyOfT>& t)
{
_root = Copy(t._root);
}
//赋值运算符重载
void operator=(const RBTree<K, T, KeyOfT>& t)
{
RBTree<K, T> new_t(t);
std::swap(new_t._root, _root);
}
//析构
~RBTree()
{
Destroy(_root);
_root = nullptr;
}
void Destroy(Node* root)
{
if (root == nullptr)
return;
Destroy(root->_left);
Destroy(root->_right);
delete root;
}
Node* Copy(const Node* root)
{
if (root == nullptr)
return nullptr;
Node* newnode = new Node(root->kv);
newnode->_left = Copy(root->_left);
newnode->_right = Copy(root->_right);
return newnode;
}
//插入
pair<Iterator,bool> Insert(const T& data);
//搜索
Iterator Find(const K& key);
//中序遍历
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);
}
private:
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);
}
//左单旋
void RotateL(Node* parent);
//右单旋
void RotateR(Node* parent);
//中序遍历(子函数)
void _InOrder(Node* root)
{
if (root == nullptr)
return;
_InOrder(root->_left);
cout << root->_kv.first << ":" << root->_kv.second << endl;
_InOrder(root->_right);
}
//树的高度
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;
}
//统计节点总个数(插入时可能会有重复数据)
int _Size(Node* root)
{
return root == nullptr ? 0 : _Size(root->_left) + _Size(root->_right) + 1;
}
private:
Node* _root = nullptr;
};
//插入
template<class K, class T, class KeyOfT>
pair<typename RBTree<K, T, KeyOfT>::Iterator,bool> RBTree<K, T, KeyOfT>::Insert(const T& data)
{
//链表为空特殊处理
if (_root == nullptr)
{
_root = new Node(data, BLACK);
return make_pair(Iterator(_root, _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, _root), false);
}
//需要插入一个新的红色节点
cur = new Node(data);
Node* newnode = cur;
if (kot(cur->_data) < kot(parent->_data))
{
parent->_left = cur;
cur->_parent = parent;
}
else
{
parent->_right = cur;
cur->_parent = parent;
}
//判断是否需要对树进行调整
while (parent && parent->_col==RED)//如果父节点颜色为红需要调整
{
Node* grandparent = parent->_parent;
if (parent == grandparent->_left) //叔叔在右
{
Node* uncle = grandparent->_right;
if (uncle && uncle->_col == RED) //当叔叔存在且为红时
{
parent->_col = uncle->_col = BLACK;
grandparent->_col = RED;
cur = grandparent;
parent = grandparent->_parent;
}
else //叔叔为黑或不存在
{
if (cur == parent->_left)//三节点同在左,右单旋
{
RotateR(grandparent);
parent->_col = BLACK;
grandparent->_col = RED;
}
else //p节点在g左,cue节点在p右,左右双旋
{
RotateL(parent);
RotateR(grandparent);
cur->_col = BLACK;
grandparent->_col = RED;
}
break;
}
}
else //叔叔在左
{
Node* uncle = grandparent->_left;
if (uncle && uncle->_col == RED) //当叔叔存在且为红时
{
parent->_col = uncle->_col = BLACK;
grandparent->_col = RED;
cur = grandparent;
parent = grandparent->_parent;
}
else //叔叔为黑或不存在
{
if (cur == parent->_right)//三节点同在右,左单旋
{
RotateL(grandparent);
parent->_col = BLACK;
grandparent->_col = RED;
}
else //p节点在g右,cue节点在p左,右左双旋
{
RotateR(parent);
RotateL(grandparent);
cur->_col = BLACK;
grandparent->_col = RED;
}
break;
}
}
}
_root->_col = BLACK;
return make_pair(Iterator(newnode, _root), true);
}
//搜索
template<class K, class T, class KeyOfT>
typename RBTree<K, T, KeyOfT>::Iterator RBTree<K, T, KeyOfT>::Find(const K& key)
{
KeyOfT kot;
Node* cur = _root;
while (cur)
{
if (kot(cur->_data) < key)
{
cur = cur->_right;
}
else if (kot(cur->_data) > key)
{
cur = cur->_left;
}
else
{
return Iterator(cur,_root);
}
}
return End();
}
//左单旋
template<class K, class T, class KeyOfT>
void RBTree<K, T, KeyOfT>::RotateL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = parent->_right->_left;
//修改向下链接内容
parent->_right = subRL;
subR->_left = parent;
//修改向上链接内容
subR->_parent = parent->_parent;
parent->_parent = subR;
if (subRL)//防止该树点为空
{
subRL->_parent = parent;
}
//parent的parent向下链接
Node* parentParent = subR->_parent;
if (parentParent == nullptr)//整棵树的根
{
_root = subR;
}
else
{
if (parent == parentParent->_right)
{
parentParent->_right = subR;
}
else
{
parentParent->_left = subR;
}
}
}
//右单旋
template<class K, class V, class KeyOfT>
void RBTree<K, V, KeyOfT>::RotateR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
//修改向下链接内容
parent->_left = subLR;
subL->_right = parent;
//修改向上链接属性
subL->_parent = parent->_parent;
parent->_parent = subL;
if (subLR)
{
subLR->_parent = parent;
}
//修改parentParent
Node* parentParent = subL->_parent;
if (parentParent == nullptr)
{
_root = subL;
}
else
{
if (parent == parentParent->_right)
{
parentParent->_right = subL;
}
else
{
parentParent->_left = subL;
}
}
}
Myset.h
#include"RBTree.h"
namespace atl
{
template <class K>
class set
{
struct SetKeyOfT
{
const K& operator()(const K& key)
{
return key;
}
};
public:
typedef typename RBTree<K, K, SetKeyOfT>::Iterator iterator;
typedef typename RBTree<K, K, SetKeyOfT>::Const_Iterator cosnt_iterator;
iterator begin()
{
return _t.Begin();
}
iterator end()
{
return _t.End();
}
cosnt_iterator begin()const
{
return _t.Begin();
}
cosnt_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);
}
private:
RBTree<K, K, SetKeyOfT> _t;
};
}
Mymap.h
#include"RBTree.h"
namespace atl
{
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>::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();
}
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;
};
}