//全局函数,用于插入新节点后重新使树形平衡,
//参数一为指向新增节点的指针,参数二为指向根节点的指针
inline void
_Rb_tree_rebalance(_Rb_tree_node_base*__x, _Rb_tree_node_base*& __root)
{
__x->_M_color = _S_rb_tree_red; //新增节点必须为红
while (__x != __root &&__x->_M_parent->_M_color == _S_rb_tree_red) { //父节点为红
//只有父节点为红是才需要进行以下调节,若为根节点只需将节点颜色改黑即可
if (__x->_M_parent ==__x->_M_parent->_M_parent->_M_left) { //父节点为祖父节点之左节点
_Rb_tree_node_base* __y =__x->_M_parent->_M_parent->_M_right;//令__y为伯父节点
if (__y && __y->_M_color ==_S_rb_tree_red) { //伯父节点存在且为红色,此时祖父必为黑
//只需改祖父节点为红,父节点和伯父节点为黑,并对祖父节点递归调用本函数即可
__x->_M_parent->_M_color =_S_rb_tree_black; //改父节点为黑色
__y->_M_color = _S_rb_tree_black; //改伯父节点为黑色
__x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;//改祖父节点为红
__x = __x->_M_parent->_M_parent; //更改__x为祖父节点,以便进行下次调整
}
else { //无伯父节点或者伯父节点为黑色
if (__x ==__x->_M_parent->_M_right) { //如果__x为父节点之右节点
__x = __x->_M_parent; //改__x为其父节点
_Rb_tree_rotate_left(__x, __root); //以新节点之父节点为旋转点进行左旋,转变为
//新节点为父节点之左节点的情形
}
//以下为新节点为父节点之左节点的情形,只需以祖父节点为旋转点右旋一次
//并改父节点颜色为黑,原祖父节点颜色为红即可
__x->_M_parent->_M_color =_S_rb_tree_black; //改父节点颜色为黑
__x->_M_parent->_M_parent->_M_color = _S_rb_tree_red;//改祖父节点颜色为红
_Rb_tree_rotate_right(__x->_M_parent->_M_parent, __root);//以祖父节点为旋转点右旋
}
}
//以下为新节点之父节点为祖父节点右节点的情况,与前面讨论的情况相似
else {
_Rb_tree_node_base* __y =__x->_M_parent->_M_parent->_M_left;//令__y为伯父节点
if (__y && __y->_M_color ==_S_rb_tree_red) { //伯父节点存在且为红色,此时祖父必为黑
//只需改祖父节点为红,父节点和伯父节点为黑,并对祖父节点递归调用本函数即可
__x->_M_parent->_M_color =_S_rb_tree_black; //改父节点为黑
__y->_M_color = _S_rb_tree_black; //改伯父节点为黑
__x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; //改祖父节点为红
__x = __x->_M_parent->_M_parent; //更改__x为祖父节点,以便进行下次调整
}
else { //无伯父节点或者伯父节点为黑色
if (__x ==__x->_M_parent->_M_left) { //如果__x为父节点之左节点
__x = __x->_M_parent; //改__x为其父节点
_Rb_tree_rotate_right(__x, __root); //以新节点之父节点为旋转点进行右旋,转变为
//新节点为父节点之右节点的情形
}
//以下为新节点为父节点之右节点的情形,只需以祖父节点为旋转点左旋一次
//并改父节点颜色为黑,原祖父节点颜色为红即可
__x->_M_parent->_M_color =_S_rb_tree_black; //改父节点颜色为黑
__x->_M_parent->_M_parent->_M_color = _S_rb_tree_red; //改祖父节点颜色为红
_Rb_tree_rotate_left(__x->_M_parent->_M_parent, __root); //以祖父节点为旋转点左旋
}
}
} //while结束点
__root->_M_color = _S_rb_tree_black; //保证根节点为黑色
}