看懂本篇博客需有树旋转基础
红黑树是近似平衡的二叉搜索树,每个节点都有红黑中一色,他满足以下几点规则
一、红节点的左右子树必须为黑色(没有连续的红节点)
二、根节点必须为黑色
三、每条路径的黑色节点必须数量相同
红黑树的节点需要三叉链用于访问parents,插入时手首先按照搜索树的规则进行插入,在创好新节点并连接后,默认新节点的颜色为红,如果parents的颜色为红,需要进行调整,因为破坏了规则一,一定不能将新节点颜色调为黑,因为破坏了规则三,这样每条路径都要进行调整,而破坏规则一只需调整一条路径,调整时会有三种情况
一、uncle存在且uncle为红(uncle指parents的parents另外一颗子树)
此时需要注意的是,parents为红,那么parents的parents(以下用grandfather代替)一定存在且为黑,因为如果parents为红,那么代表他不是根,而如果grandfather为红,早已被调整过,所以grandfather一定为黑,下面是一副具象图:
此时为了既能保证黑节点总数不变,又能保证没有连续的红节点,我们选择将grandfater变红,parents和uncle变黑,变化后如图
这样做既可以使得grandfather的所有路径黑节点数量不变,也可使得没有连续的树中没有连续的红节点,这样做有一个隐患是grandfather->parents可能为红,所以需要继续向上更新,直到没有连续的红节点或parents为空为止。
二、uncle不存在或存在为黑(旋转一次)
uncle不存在或存在为黑处理方法相同,以uncle存在为黑举例如图
此时需要将grandfather进行一次右旋转,旋转后如图:
再将grandfather变为红,parents变为黑,黑节点数量依旧不变,同样没有连续的红节点,变色后如图
三、uncle不存在或uncle为黑(需双旋)
此时需要将parents先进行一次旋转,旋转后如图
此时情况就和第二种情况一样了,只是new和parents的位置不同,只需将new和parents的指针进行调换即可完美将第三种情况变为第二种
bool insert(const T& data)
{
if (_root == nullptr)
{
_root = new TreeNode(data);
_root->color = BLACK;
return true;
}
KOfT koft;
TreeNode* cur = _root;
TreeNode* parents = nullptr;
while (cur)
{
if (koft(cur->_data) < koft(data))
{
parents = cur;
cur = cur->_right;
}
else if (koft(cur->_data) > koft(data))
{
parents = cur;
cur = cur->_left;
}
else
{
return false;
}
}
cur = new TreeNode(data);
if (koft(parents->_data) < koft(cur->_data))
{
parents->_right = cur;
cur->_parents = parents;
}
else
{
parents->_left = cur;
cur->_parents = parents;
}
cur->color = RED;
while (parents && parents->color == RED)
{
TreeNode* grandfather = parents->_parents;
if (grandfather->_left == parents)
{
TreeNode* uncle = grandfather->_right;
//uncle 存在且为红
if (uncle && uncle->color == RED)
{
grandfather->color = RED;
parents->color = BLACK;
uncle->color = BLACK;
//继续向上更新
cur = grandfather;
parents = cur->_parents;
}
//uncle 不存在 或 uncle存在且为黑
else
{
//将双旋变为单旋
if (cur == parents->_right)
{
Left_Rotate(parents);
swap(parents, cur);
}
Right_Rotate(grandfather);
grandfather->color = RED;
parents->color = BLACK;
break;
}
}
else if(grandfather->_right == parents)
{
TreeNode* uncle = grandfather->_left;
//uncle 存在且为红
if (uncle && uncle->color == RED)
{
grandfather->color = RED;
parents->color = BLACK;
uncle->color = BLACK;
//继续向上更新
cur = grandfather;
parents = cur->_parents;
}
else
{
//将双旋变为单旋
if (cur == parents->_left)
{
Right_Rotate(parents);
std::swap(parents, cur);
}
Left_Rotate(grandfather);
grandfather->color = RED;
parents->color = BLACK;
break;
}
}
}
_root->color = BLACK;
return true;
}
void Left_Rotate(TreeNode* parents)
{
TreeNode* subR = parents->_right;
TreeNode* subRL = subR->_left;
TreeNode* ppnode = parents->_parents;
subR->_left = parents;
parents->_right = subRL;
//旋转时如果subRL为空,则不需要parents
if (subRL)
subRL->_parents = parents;
parents->_parents = subR;
//parents->parents为空,说明parents为root
if (_root == parents)
{
_root = subR;
subR->_parents = nullptr;
}
else
{
if (ppnode->_left == parents)
ppnode->_left = subR;
else
ppnode->_right = subR;
subR->_parents = ppnode;
}
//parents->_bf = 0;
//if (subR)
//{
// subR->_bf = 0;
// subR->_parents = ppnode;
//}
}
void Right_Rotate(TreeNode* parents)
{
TreeNode* subL = parents->_left;
TreeNode* ppnode = parents->_parents;
TreeNode* subLR = subL->_right;
subL->_right = parents;
parents->_left = subLR;
if (subLR)
subLR->_parents = parents;
parents->_parents = subL;
if (_root == parents)
{
_root = subL;
subL->_parents = nullptr;
}
else
{
if (ppnode->_left == parents)
ppnode->_left = subL;
else
ppnode->_right = subL;
subL->_parents = ppnode;
}
/* parents->_bf = 0;
if (subL)
subL->_bf = 0;*/
}
红黑树的迭代器实现
enum _RB_Tree_color
{
RED,
BLACK
};
template<typename T>
struct __RB_Tree_Node
{
__RB_Tree_Node<T>* _left;
__RB_Tree_Node<T>* _right;
__RB_Tree_Node<T>* _parents;
T _data;
_RB_Tree_color color;
__RB_Tree_Node(const T& kv) :_left(nullptr), _right(nullptr), _parents(nullptr), _data(kv), color(RED) {}
};
template<typename T>
class _RB_Tree_iterator
{
typedef __RB_Tree_Node<T> Node;
typedef _RB_Tree_iterator<T> self;
Node* _node;
public:
_RB_Tree_iterator(Node* node) :_node(node) {}
T& operator*()
{
return this->_node->_data;
}
T* operator->()
{
return &(_node->_data);
}
bool operator!=(const self& node)
{
return this->_node != node._node;
}
bool operator==(const self& node)
{
return this->_node == node._node;
}
//
self& operator++()
{
if (_node->_right)
{
Node* subleft = _node->_right;
while (subleft->_left)
{
subleft = subleft->_left;
}
_node = subleft;
}
else
{
Node* cur = _node;
Node* parents = _node->_parents;
while (parents && parents->_right == cur)
{
cur = parents;
parents = parents->_parents;
}
_node = parents;
}
return *this;
}
void operator--()
{
//左子树不为空
if (_node->_left)
{
Node* subleft = _node->_left;
_node = subleft;
}
//左子树为空
else
{
//如果我是父亲的右树,那么减到父亲,
//如果我是父亲的左树,代表左树已经访问完,我成为我的父亲,并继续判断
Node* cur = _node;
Node* parents = _node->_parents;
while (parents && parents->_left == cur)
{
cur = parents;
parents = parents->_parents;
}
_node = parents;
}
}
};