红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。
没有AVL树那么严格的要求必须左右子树高度差小于1。
为了后续实现关联式容器简单,红黑树的实现中增加一个头结点,因为根节点必须为黑色,为了与根节点进行区分,将头结点给成黑色,并且让头结点的 pParent 域指向红黑树的根节点,pLeft域指向红黑树中最小的节点,_pRight域指向红黑树中最大的节点。
enum COLOR
{
BLACK,
RED
};
template <class K, class V>
struct RBNode
{
RBNode<K, V>* _parent;
RBNode<K, V>* _left;
RBNode<K, V>* _right;
//key - value
pair<K, V> _kv;
COLOR _color;
RBNode(const pair<K, V>& kv = pair<K, V>())
:_parent(nullptr)
, _left(nullptr)
, _right(nullptr)
, _kv(kv)
, _color(RED)
{}
};
template <class K, class V>
class RBTree
{
public:
typedef RBNode<K, V> Node;
RBTree()
:_header(new Node)
{
//创建空树
_header->_left = _header->_right = _header;
}
private:
Node* _header;
};
bool insert(const pair<K, V>& kv)
{
//1.搜索树的插入
// 空树:_header->parent:nullptr
if (_header->_parent = nullptr)
{
//创建根节点
Node* root = new Node(kv);
_header->_parent = root;
root->_parent = _header;
_header->_left = _header->_right = root;
//根节点是黑色
root->_color = BLACK;
return true;
}
//从根节点开始搜索
Node* cur = _header->_parent;
Node* parent = nullptr;
while (cur)
{
parent = cur;
//和key值进行比较
//kv:pair, key:pair.first
if (cur->_kv.first == kv.first)
{
//key值不允许重复
return false;
}
else if (cur->_kv.first > kv.first)
{
cur = cur->_left;
}
else
{
cur = cur->_right;
}
}
//创建待插入的节点
cur = new Node(kv);
if (parent->_kv.first > kv.first)
parent->_left = cur;
else
parent->_right = cur;
cur->_parent = parent;
//2.修改颜色或者调整结构
//判断是否有红色连续的节点
while (cur != _header->_parent && cur->_parent->_color == RED)
{
parent = cur->_parent;
Node* gfather = parent->_parent;
if (gfather->_left == parent)
{
Node* uncle = gfather->_right;
//1.uncle存在,并且是红色的
if (uncle && uncle->_color == RED)
{
parent->_color = uncle->_color = BLACK;
gfather->_color = RED;
//继续更新
cur = gfather;
}
else
{
//判断是否为双旋的场景
if (cur == parent->_right)
{
//左旋
RotateL(parent);
//交换cur,parent指向,退化为右旋的场景
swap(cur, parent);
}
//右旋
RotateR(gfather);
parent->_color = BLACK;
gfather->_color = RED;
break;
}
}
else
{
//gfather->_right == parent
Node* uncle = gfather->_left;
//1.uncle存在,并且是红色的
if (uncle && uncle->_color == RED)
{
parent->_color = uncle->_color = BLACK;
gfather->_color = RED;
//继续更新
cur = gfather;
}
else
{
//判断是否为双旋的场景
if (cur == parent->_left)
{
//右旋
RotateR(parent);
//交换cur,parent指向,退化为右旋的场景
swap(cur, parent);
}
//左旋
RotateL(gfather);
parent->_color = BLACK;
gfather->_color = RED;
break;
}
}
}
//根节点的颜色改成黑色
_header->_parent->_color = BLACK;
//更新header的左右指向
_header->_left = leftMost();
_header->_right = rightMost();
}
//右旋操作结构如下:
// parent(-2)
//subL(-1)
// subLR(0)
void RotateR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
subL->_right = parent;
parent->_left = subLR;
if (subLR)
subLR->_parent = parent;
//更新cur和父亲的父亲之间的连接
//判断是否为根节点
if (parent == _root)
{
_root = subL;
subL->_parent = nullptr;
}
else
{
Node* pparent = parent->_parent;
if (pparent->_left == parent)
pparent->_left = subL;
else
pparent->_right = subL;
subL->_parent = pparent;
}
//更新父亲的父亲为cur
parent->_parent = subL;
//更新平衡因子
subL->_bf = parent->_bf = 0;
}
//左旋操作结构如下:
//parent(2)
// subR(1)
// subRL(0)
void RotateL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
subR->_left = parent;
parent->_right = subRL;
if (subRL)
subRL->_parent = parent;
//更新cur和父亲的父亲之间的连接
//判断是否为根节点
if (parent == _root)
{
_root = subR;
subR->_parent = nullptr;
}
else
{
Node* pparent = parent->_parent;
if (pparent->_left == parent)
pparent->_left = subR;
else
pparent->_right = subR;
subR->_parent = pparent;
}
//更新父亲的父亲为cur
parent->_parent = subR;
//更新平衡因子
subR->_bf = parent->_bf = 0;
}
Node* leftMost()
{
Node* cur = _header->_parent;
while (cur && cur->_left)
{
cur = cur->_left;
}
return cur;
}
Node* rightMost()
{
Node* cur = _header->_parent;
while (cur && cur->_right)
{
cur = cur->_right;
}
return cur;
}
void inorder()
{
_inorder(_header->_parent);
cout << endl;
}
void _inorder(Node* root)
{
if (root)
{
_inorder(root->_left);
cout << root->_kv.first << " " << root->_kv.second;
_inorder(root->_right);
}
}
//红黑树:
//1.根:黑色
//2.每条路径黑色个数相同
//3.红色不能连续
bool isBalance()
{
if (_header->_parent == nullptr)
return true;
Node* root = _header->_parent;
if (root->_color == RED)
return false;
//统计一条路径上的黑色节点个数
int bCount = 0;
Node* cur = root;
while (cur)
{
if (cur->_color == BLACK)
++bCount;
cur = cur->_left;
}
//遍历每一条路径
int curBCount = 0;
return _isBalance(root, bCount, curBCount);
}
bool _isBalance(Node* root, int& bCount, int curBCount)
{
//当root为空时,一条路径遍历结束
if (root == nullptr)
{
//判断黑色节点个数是否相同
if (curBCount != bCount)
return false;
else
return true;
}
//判断节点是否为黑色
if (root->_color == BLACK)
++curBCount;
//判断是否由红色连续的节点
if (root->_parent && root->_color == RED && root->_parent->_color == RED)
{
cout << "data:" << root->_kv.first << endl;
return false;
}
return _isBalance(root->_left) && _isBalance(root->_right);
}
enum COLOR
{
BLACK,
RED
};
template <class K, class V>
struct RBNode
{
RBNode<K, V>* _parent;
RBNode<K, V>* _left;
RBNode<K, V>* _right;
//key - value
pair<K, V> _kv;
COLOR _color;
RBNode(const pair<K, V>& kv = pair<K, V>())
:_parent(nullptr)
, _left(nullptr)
, _right(nullptr)
, _kv(kv)
, _color(RED)
{}
};
template <class K, class V>
class RBTree
{
public:
typedef RBNode<K, V> Node;
RBTree()
:_header(new Node)
{
//创建空树
_header->_left = _header->_right = _header;
}
bool insert(const pair<K, V>& kv)
{
//1.搜索树的插入
// 空树:_header->parent:nullptr
if (_header->_parent = nullptr)
{
//创建根节点
Node* root = new Node(kv);
_header->_parent = root;
root->_parent = _header;
_header->_left = _header->_right = root;
//根节点是黑色
root->_color = BLACK;
return true;
}
//从根节点开始搜索
Node* cur = _header->_parent;
Node* parent = nullptr;
while (cur)
{
parent = cur;
//和key值进行比较
//kv:pair, key:pair.first
if (cur->_kv.first == kv.first)
{
//key值不允许重复
return false;
}
else if (cur->_kv.first > kv.first)
{
cur = cur->_left;
}
else
{
cur = cur->_right;
}
}
//创建待插入的节点
cur = new Node(kv);
if (parent->_kv.first > kv.first)
parent->_left = cur;
else
parent->_right = cur;
cur->_parent = parent;
//2.修改颜色或者调整结构
//判断是否有红色连续的节点
while (cur != _header->_parent && cur->_parent->_color == RED)
{
parent = cur->_parent;
Node* gfather = parent->_parent;
if (gfather->_left == parent)
{
Node* uncle = gfather->_right;
//1.uncle存在,并且是红色的
if (uncle && uncle->_color == RED)
{
parent->_color = uncle->_color = BLACK;
gfather->_color = RED;
//继续更新
cur = gfather;
}
else
{
//判断是否为双旋的场景
if (cur == parent->_right)
{
//左旋
RotateL(parent);
//交换cur,parent指向,退化为右旋的场景
swap(cur, parent);
}
//右旋
RotateR(gfather);
parent->_color = BLACK;
gfather->_color = RED;
break;
}
}
else
{
//gfather->_right == parent
Node* uncle = gfather->_left;
//1.uncle存在,并且是红色的
if (uncle && uncle->_color == RED)
{
parent->_color = uncle->_color = BLACK;
gfather->_color = RED;
//继续更新
cur = gfather;
}
else
{
//判断是否为双旋的场景
if (cur == parent->_left)
{
//右旋
RotateR(parent);
//交换cur,parent指向,退化为右旋的场景
swap(cur, parent);
}
//左旋
RotateL(gfather);
parent->_color = BLACK;
gfather->_color = RED;
break;
}
}
}
//根节点的颜色改成黑色
_header->_parent->_color = BLACK;
//更新header的左右指向
_header->_left = leftMost();
_header->_right = rightMost();
}
//右旋操作结构如下:
// parent(-2)
//subL(-1)
// subLR(0)
void RotateR(Node* parent)
{
Node* subL = parent->_left;
Node* subLR = subL->_right;
subL->_right = parent;
parent->_left = subLR;
if (subLR)
subLR->_parent = parent;
//更新cur和父亲的父亲之间的连接
//判断是否为根节点
if (parent == _root)
{
_root = subL;
subL->_parent = nullptr;
}
else
{
Node* pparent = parent->_parent;
if (pparent->_left == parent)
pparent->_left = subL;
else
pparent->_right = subL;
subL->_parent = pparent;
}
//更新父亲的父亲为cur
parent->_parent = subL;
//更新平衡因子
subL->_bf = parent->_bf = 0;
}
//左旋操作结构如下:
//parent(2)
// subR(1)
// subRL(0)
void RotateL(Node* parent)
{
Node* subR = parent->_right;
Node* subRL = subR->_left;
subR->_left = parent;
parent->_right = subRL;
if (subRL)
subRL->_parent = parent;
//更新cur和父亲的父亲之间的连接
//判断是否为根节点
if (parent == _root)
{
_root = subR;
subR->_parent = nullptr;
}
else
{
Node* pparent = parent->_parent;
if (pparent->_left == parent)
pparent->_left = subR;
else
pparent->_right = subR;
subR->_parent = pparent;
}
//更新父亲的父亲为cur
parent->_parent = subR;
//更新平衡因子
subR->_bf = parent->_bf = 0;
}
Node* leftMost()
{
Node* cur = _header->_parent;
while (cur && cur->_left)
{
cur = cur->_left;
}
return cur;
}
Node* rightMost()
{
Node* cur = _header->_parent;
while (cur && cur->_right)
{
cur = cur->_right;
}
return cur;
}
void inorder()
{
_inorder(_header->_parent);
cout << endl;
}
void _inorder(Node* root)
{
if (root)
{
_inorder(root->_left);
cout << root->_kv.first << " " << root->_kv.second;
_inorder(root->_right);
}
}
//红黑树:
//1.根:黑色
//2.每条路径黑色个数相同
//3.红色不能连续
bool isBalance()
{
if (_header->_parent == nullptr)
return true;
Node* root = _header->_parent;
if (root->_color == RED)
return false;
//统计一条路径上的黑色节点个数
int bCount = 0;
Node* cur = root;
while (cur)
{
if (cur->_color == BLACK)
++bCount;
cur = cur->_left;
}
//遍历每一条路径
int curBCount = 0;
return _isBalance(root, bCount, curBCount);
}
bool _isBalance(Node* root, int& bCount, int curBCount)
{
//当root为空时,一条路径遍历结束
if (root == nullptr)
{
//判断黑色节点个数是否相同
if (curBCount != bCount)
return false;
else
return true;
}
//判断节点是否为黑色
if (root->_color == BLACK)
++curBCount;
//判断是否由红色连续的节点
if (root->_parent && root->_color == RED && root->_parent->_color == RED)
{
cout << "data:" << root->_kv.first << endl;
return false;
}
return _isBalance(root->_left) && _isBalance(root->_right);
}
private:
Node* _header;
};
void test()
{
RBTree<int, int> rbt;
rbt.insert(make_pair(10, 10));
rbt.insert(make_pair(15, 15));
rbt.insert(make_pair(5, 5));
rbt.insert(make_pair(2, 2));
}
int main()
{
test();
return 0;
}