目录
- 红黑树理解
- 红黑树概念
- 红黑树性质
- 红黑树实现
- 红黑树图解
- 基础结构实现
- 插入实现
红黑树理解
红黑树概念
红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是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<K,V>, 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
{
Node* uncle = gfather->_left;
//1.uncle存在,并且是红色的
if (uncle && uncle->_color == RED)
{
parent->_color = uncle->_color = BLACK;
gfather->_color = RED;
//继续更新
cur = gfather;
}
}
}
//根节点的颜色改成黑色
_header->_parent->_color = BLACK;
//更新header的左右指向
_header->_left = leftMost();
_header->_right = rightMost();
}
尚未结束~~持续更新