目录
- 一. 原型
- 二. 模板参数适配
- 三. 迭代器
- 四. 插入函数的修改
- 四. 代码
一. 原型
- 简单实现的红黑树
template<class K, class V>
struct RBTreeNode
{
RBTreeNode<K, V>* _left;
RBTreeNode<K, V>* _right;
RBTreeNode<K, V>* _parent;
pair<K, V> _kv;
Colour _col;
};
template<class K, class V>
struct RBTree
{
typedef RBTreeNode<K, V> Node;
public:
bool Insert(const pair<K, V>& kv);
Node* Find(const K& key);
private:
Node* _root = nullptr;
};
- set
template<class K>
class set
{
private:
RBTree<K, K> _t;
};
- map
template<class K, class V>
class map
{
private:
RBTree<K, V> _t;
};
二. 模板参数适配
- 红黑树
template<class T>
struct RBTreeNode
{
RBTreeNode<T>* _left;
RBTreeNode<T>* _right;
RBTreeNode<T>* _parent;
T _data;
Colour _col;
};
template<class K, class T, class KeyOfT>
struct RBTree
{
typedef RBTreeNode<T> Node;
public:
bool Insert(const T& data);
Node* Find(const K& key);
private:
Node* _root = nullptr;
}
- set
template<class K>
class set
{
//仿函数
struct SetKeyOfT//返回K对象的key
{
const K& operator()(const K& key)
{
return key;
}
};
private:
RBTree<K, K, SetKeyOfT> _t;
};
- map
template<class K, class V>
class map
{
struct MapKeyOfT//返回pair<K,V>对象的key
{
const K& operator()(const pair<K, V>& kv)
{
return kv.first;
}
};
private:
RBTree<K, pair<K,V>, MapKeyOfT> _t;
};
红黑树作为底层结构而言,它不能够区分使用者是set还是map。
class K:表示键值类型
class T:表示存储类型
class KeyOfT:仿函数,用于从T类型中提取K键值
对于set容器,底层存储K类型元素,键值也为K
对于map容器,底层存储<K,V>键值对,键值为K
三. 迭代器
设计迭代器,方便遍历,让用户在使用时不需要在意底层实现。
template<class T, class Ref, class Ptr>
struct __RBTreeIterator
{
typedef RBTreeNode<T> Node;
typedef __RBTreeIterator<T, Ref, Ptr> Self;
Node* _node;
__RBTreeIterator(Node* node)
:_node(node)
{}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &_node->_data;
}
bool operator!=(const Self& s) const
{
return _node != s._node;
}
bool operator==(const Self& s) const
{
return _node == s._node;
}
Self& operator++();
Self& operator--();
};
template<class K, class T, class KeyOfT>
struct RBTree
{
typedef __RBTreeIterator<T, T&, T*> iterator;
public:
// 最左节点
iterator begin()
{
Node* left = _root;
while (left && left->_left)
{
left = left->_left;
}
return iterator(left);
}
// 最后一个节点的下一个位置
iterator end()
{
return iterator(nullptr);
}
};
operator++()
步骤:
- 右子树不为空,++就是找右子树中序第一个(最左节点)
- 右子树为空,++找孩子不是父亲右的那个祖先
Self& operator++()
{
if (_node->_right)
{
// 下一个就是右子树的最左节点
Node* left = _node->_right;
while (left->_left)
{
left = left->_left;
}
_node = left;
}
else
{
// 找祖先里面孩子不是祖先的右的那个
Node* parent = _node->_parent;
Node* cur = _node;
while (parent && cur == parent->_right)
{
cur = cur->_parent;
parent = parent->_parent;
}
_node = parent;
}
return *this;
}
operator--()
与++相反,步骤:
- 左子树不为空,–就是找左子树的最右节点
- 左子树为空,–找孩子不是父亲的左的那个祖先
Self& operator--()
{
if (_node->_left)
{
// 下一个是左子树的最右节点
Node* right = _node->_left;
while (right->_right)
{
right = right->_right;
}
_node = right;
}
else
{
// 孩子不是父亲的左的那个祖先
Node* parent = _node->_parent;
Node* cur = _node;
while (parent && cur == parent->_left)
{
cur = cur->_parent;
parent = parent->_parent;
}
_node = parent;
}
return *this;
}
四. 插入函数的修改
pair<iterator, bool> Insert(const T& data)
{
KeyOfT kot;//仿函数,获取键值
if (_root == nullptr)//空树,让新节点为根节点
{
_root = new Node(data);
_root->_col = BLACK;
return make_pair(iterator(_root), true);;
}
//插入新节点
Node* cur = _root;//当前节点
Node* parent = nullptr;//cur的父节点
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;//标记新节的
if (kot(parent->_data) < kot(data))//新节点的键值大于parent
{
parent->_right = cur;//放在parent的右边
}
else
{
parent->_left = cur;//左边
}
cur->_parent = parent;
// 调整
//(cur最差会遍历到根节点)p为红色
while (parent && parent->_col == RED)
{
Node* grandfater = parent->_parent;//parent的父节点
// 关键看叔叔
if (parent == grandfater->_left)//p是g的左孩子
{
Node* uncle = grandfater->_right;//叔叔节点
// 情况一 : u为红,
if (uncle && uncle->_col == RED)
{
// 变色
parent->_col = uncle->_col = BLACK;
grandfater->_col = RED;
// 继续往上处理
cur = grandfater;
parent = cur->_parent;
}
else// 情况二:u为黑
{
if (cur == parent->_left)//c为p的左孩子
{
// 右单旋+变色
// g
// p u
// c
RotateR(grandfater);//右旋
parent->_col = BLACK;
grandfater->_col = RED;
}
else//c为p的右孩子
{
// 左右单旋+变色
// g
// p u
// c
RotateL(parent);//左旋
RotateR(grandfater);//右旋
cur->_col = BLACK;
grandfater->_col = RED;
}
break;//结束
}
}
else // (parent == grandfater->_right) //p是g的右孩子
{
Node* uncle = grandfater->_left;//叔叔节点
// 情况一 : u为红,
if (uncle && uncle->_col == RED)
{
// 变色
parent->_col = uncle->_col = BLACK;
grandfater->_col = RED;
// 继续往上处理
cur = grandfater;
parent = cur->_parent;
}
else//情况二 : u为黑,
{
if (cur == parent->_right)//c为p的右孩子
{
// 左单旋+变色
// g
// u p
// c
RotateL(grandfater);//左旋
parent->_col = BLACK;
grandfater->_col = RED;
}
else// c为p的左孩子
{
// 情况三:右左单旋+变色
// g
// u p
// c
RotateR(parent);//右旋
RotateL(grandfater);//左旋
cur->_col = BLACK;
grandfater->_col = RED;
}
break;//结束
}
}
}
_root->_col = BLACK;//根节点颜色为黑色(可能在情况一下被修改)
return make_pair(iterator(newnode), true);
}
将Insert()的返回值改为pair<iterator, bool>
的形式,主要是为了实现map中的operator[]
V& operator[](const K& key)
{
pair<iterator, bool> ret = insert(make_pair(key, V()));
return ret.first->second;
}
四. 代码
- 红黑树
#pragma once
enum Colour
{
RED,
BLACK
};
template<class T>
struct RBTreeNode
{
RBTreeNode<T>* _left;
RBTreeNode<T>* _right;
RBTreeNode<T>* _parent;
T _data;
Colour _col;
RBTreeNode(const T& data)
:_left(nullptr)
, _right(nullptr)
, _parent(nullptr)
, _data(data)
, _col(RED)
{}
};
template<class T, class Ref, class Ptr>
struct __RBTreeIterator
{
typedef RBTreeNode<T> Node;
typedef __RBTreeIterator<T, Ref, Ptr> Self;
Node* _node;
__RBTreeIterator(Node* node)
:_node(node)
{}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &_node->_data;
}
bool operator!=(const Self& s) const
{
return _node != s._node;
}
bool operator==(const Self& s) const
{
return _node == s._node;
}
Self& operator++()
{
if (_node->_right)
{
// 下一个就是右子树的最左节点
Node* left = _node->_right;
while (left->_left)
{
left = left->_left;
}
_node = left;
}
else
{
// 找祖先里面孩子不是祖先的右的那个
Node* parent = _node->_parent;
Node* cur = _node;
while (parent && cur == parent->_right)
{
cur = cur->_parent;
parent = parent->_parent;
}
_node = parent;
}
return *this;
}
Self& operator--()
{
if (_node->_left)
{
// 下一个是左子树的最右节点
Node* right = _node->_left;
while (right->_right)
{
right = right->_right;
}
_node = right;
}
else
{
// 孩子不是父亲的左的那个祖先
Node* parent = _node->_parent;
Node* cur = _node;
while (parent && cur == parent->_left)
{
cur = cur->_parent;
parent = parent->_parent;
}
_node = parent;
}
return *this;
}
};
template<class K, class T, class KeyOfT>
struct RBTree
{
typedef RBTreeNode<T> Node;
typedef __RBTreeIterator<T, T&, T*> iterator;
public:
iterator begin()
{
Node* left = _root;
while (left && left->_left)
{
left = left->_left;
}
return iterator(left);
}
iterator end()
{
return iterator(nullptr);
}
pair<iterator, bool> Insert(const T& data)
{
KeyOfT kot;
if (_root == nullptr)//空树,让新节点为根节点
{
_root = new Node(data);
_root->_col = BLACK;
return make_pair(iterator(_root), true);;
}
//插入新节点
Node* cur = _root;//当前节点
Node* parent = nullptr;//cur的父节点
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;//标记新节的
if (kot(parent->_data) < kot(data))//新节点的键值大于parent
{
parent->_right = cur;//放在parent的右边
}
else
{
parent->_left = cur;//左边
}
cur->_parent = parent;
// 调整
//(cur最差会遍历到根节点)p为红色
while (parent && parent->_col == RED)
{
Node* grandfater = parent->_parent;//parent的父节点
// 关键看叔叔
if (parent == grandfater->_left)//p是g的左孩子
{
Node* uncle = grandfater->_right;//叔叔节点
// 情况一 : u为红,
if (uncle && uncle->_col == RED)
{
// 变色
parent->_col = uncle->_col = BLACK;
grandfater->_col = RED;
// 继续往上处理
cur = grandfater;
parent = cur->_parent;
}
else// 情况二:u为黑
{
if (cur == parent->_left)//c为p的左孩子
{
// 右单旋+变色
// g
// p u
// c
RotateR(grandfater);//右旋
parent->_col = BLACK;
grandfater->_col = RED;
}
else//c为p的右孩子
{
// 左右单旋+变色
// g
// p u
// c
RotateL(parent);//左旋
RotateR(grandfater);//右旋
cur->_col = BLACK;
grandfater->_col = RED;
}
break;//结束
}
}
else // (parent == grandfater->_right) //p是g的右孩子
{
Node* uncle = grandfater->_left;//叔叔节点
// 情况一 : u为红,
if (uncle && uncle->_col == RED)
{
// 变色
parent->_col = uncle->_col = BLACK;
grandfater->_col = RED;
// 继续往上处理
cur = grandfater;
parent = cur->_parent;
}
else//情况二 : u为黑,
{
if (cur == parent->_right)//c为p的右孩子
{
// 左单旋+变色
// g
// u p
// c
RotateL(grandfater);//左旋
parent->_col = BLACK;
grandfater->_col = RED;
}
else// c为p的左孩子
{
// 情况三:右左单旋+变色
// g
// u p
// c
RotateR(parent);//右旋
RotateL(grandfater);//左旋
cur->_col = BLACK;
grandfater->_col = RED;
}
break;//结束
}
}
}
_root->_col = BLACK;//根节点颜色为黑色(可能在情况一下被修改)
return make_pair(iterator(newnode), true);
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
bool IsRBTree()
{
if (_root == nullptr)
{
return true;
}
if (_root->_col == RED)
{
cout << "根节点不是黑色" << endl;
return false;
}
int benchmark = 0;// 黑色节点数量基准值
return PrevCheck(_root, 0, benchmark);
}
private:
// 休息21:18继续
bool PrevCheck(Node* root, int blackNum, int& benchmark)
{
if (root == nullptr)//路径走完,到空节点
{
//benchark更新为第一条路径上黑色节点的数量
if (benchmark == 0)
{
benchmark = blackNum;
return true;
}
if (blackNum != benchmark)
{
cout << "某条路径黑色节点的数量不相等" << endl;
return false;
}
else
{
return true;
}
}
if (root->_col == BLACK)
{
++blackNum;
}
if (root->_col == RED && root->_parent->_col == RED)
{
cout << "存在连续的红色节点" << endl;
return false;
}
return PrevCheck(root->_left, blackNum, benchmark)
&& PrevCheck(root->_right, blackNum, benchmark);
}
void _InOrder(Node* root)
{
KeyOfT kot;
if (root == nullptr)
{
return;
}
_InOrder(root->_left);
cout << kot(root->_data) << ":" << root->_data << endl;
_InOrder(root->_right);
}
void RotateL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
parent->_right = subRL;
if (subRL)
subRL->_parent = parent;
Node* ppNode = parent->_parent;
subR->_left = parent;
parent->_parent = subR;
if (_root == parent)
{
_root = subR;
subR->_parent = nullptr;
}
else
{
if (ppNode->_left == parent)
{
ppNode->_left = subR;
}
else
{
ppNode->_right = subR;
}
subR->_parent = ppNode;
}
}
void RotateR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
parent->_left = subLR;
if (subLR)
{
subLR->_parent = parent;
}
Node* ppNode = parent->_parent;
subL->_right = parent;
parent->_parent = subL;
if (_root == parent)
{
_root = subL;
subL->_parent = nullptr;
}
else
{
if (ppNode->_left == parent)
{
ppNode->_left = subL;
}
else
{
ppNode->_right = subL;
}
subL->_parent = ppNode;
}
}
private:
Node* _root = nullptr;
};
- set
#pragma once
#include "RBTree.h"
template<class K>
class set
{
struct SetKeyOfT
{
const K& operator()(const K& key)
{
return key;
}
};
public:
typedef typename RBTree<K, K, SetKeyOfT>::iterator iterator;
iterator begin()
{
return _t.begin();
}
iterator end()
{
return _t.end();
}
pair<iterator, bool> insert(const K& key)
{
return _t.Insert(key);
}
private:
RBTree<K, K, SetKeyOfT> _t;
};
- map
#pragma once
#include "RBTree.h"
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<K, V>, MapKeyOfT>::iterator iterator;
iterator begin()
{
return _t.begin();
}
iterator end()
{
return _t.end();
}
pair<iterator, bool> insert(const pair<K, V>& kv)
{
return _t.Insert(kv);
}
V& operator[](const K& key)
{
pair<iterator, bool> ret = insert(make_pair(key, V()));
return ret.first->second;
}
private:
RBTree<K, pair<K, V>, MapKeyOfT> _t;
};
🦀🦀观看~~