这篇为红黑树删除,可以算作上一篇红黑树的构建与插入的下一篇
这里单独贴出删除节点的代码:
__rb_tree_node_base* _Rb_tree_rebalance_for_erase(__rb_tree_node_base* const __z,
__rb_tree_node_base& __header)
{
__rb_tree_node_base*& __root = __header.parent;
__rb_tree_node_base*& __leftmost = __header.left;
__rb_tree_node_base*& __rightmost = __header.right;
__rb_tree_node_base* __y = __z;
__rb_tree_node_base* __x = 0;
__rb_tree_node_base* __x_parent = 0;
if(__y->left == 0)
{//在这里z最多有一个非空的子节点
//如果删除节点的左子节点不存在则将删除节点的右子节点赋值给x
//x可以为空
__x = __y->right;
}
else
{
if(__y->right == 0)
{//这里z一定有一个非空子节点
__x = __y->left;//x一定不为空
}
else
{
//这里z有两个非空子节点
__y = __y->right;//将y设置为z的后继节点,x可以为空
while(__y->left != 0)
{
//这里的目的是找到一个值最接近被删除节点值的叶子节点用于替换被删除节点删除后的空位
__y = __y->left;
}
__x = __y->right;
}
}
if(__y != __z)
{
//开始用y代替z的位置(y是z的后继节点)
__z->left->parent = __y;//将z的左子节点指向的父节点指向y
__y->left = __z->left;//接着将y指向的左子节点指向z的左子节点
if(__y != __z->right)
{
__x_parent = __y->parent;
if(__x)
{
__x->parent = __y->parent;
}
__y->parent->left = __x;//y一定有一个左孩子节点
__y->right = __z->right;
__z->right->parent = __y;
}
else
{
__x_parent = __y;
}
if(__root == __z)
{
__root = __y;
}
else if(__z->parent->left == __z)
{
__z->parent->left = __y;
}
else
{
__z->parent->right = __y;
__y->parent = __z->parent;
std::swap(__y->color, __z->color);
__y = __z;
//到这里所有的与z相关的节点都与z解除了关联并与y建立了关联,z可以被删除了
}
}
else
{//这里是__y==__z的情况
__x_parent = __y->parent;
if(__x)
{
__x->parent = __y->parent;
}
if(__root == __z)
{
__root = __x;
}
else
{
if(__z->parent->left == __z)
{
__z->parent->left = __x;
}
else
{
__z->parent->right =__x;
}
}
if(__leftmost == __z)
{
if(__z->right == 0) //如果z的右子节点为空,z的左子节点也必须为空
{
__leftmost = __z->parent;
//如果z等于root那么__leftmost等于_M_header
}
else
{
__leftmost = __rb_tree_node_base::minimum(__x);
}
}
if(__rightmost == __z)
{
__rightmost = __z->parent;
//如果z等于root那么__rightmost等于_M_header
}
else
{
__rightmost = __rb_tree_node_base::maximum(__x);
}
}
//开始调整颜色与旋转
if(__y->color != __rb_tree_red)
{
while(__x != __root && (__x == 0 || __x->color == __rb_tree_black))
{
if(__x == __x_parent->left)
{
__rb_tree_node_base* __w = __x_parent->right;
if(__w->color == __rb_tree_red)
{
__w->color = __rb_tree_black;
__w->parent->color = __rb_tree_red;
local_Rb_tree_rotate_left(__x_parent, __root);
__w = __x_parent->right;
}
if((__w->left == 0 ||
__w->left->color == __rb_tree_black) &&
(__w->right == 0 ||
__w->right->color == __rb_tree_black))
{
__w->color = __rb_tree_red;
__x = __x_parent;
__x_parent = __x_parent->parent;
}
else
{
if(__w->right == 0 ||
__w->right->color == __rb_tree_black)
{
__w->left->color = __rb_tree_black;
__w->color = __rb_tree_red;
local_Rb_tree_rotate_right(__w, __root);
__w = __x_parent->right;
}
__w->color = __x_parent->color;
__x_parent->color = __rb_tree_black;
if(__w->right)
{
__w->right->color = __rb_tree_black;
}
local_Rb_tree_rotate_left(__x_parent, __root);
break;
}
}
else
{
//该分支与上方操作相同只是进行了左右节点的互换
__rb_tree_node_base* __w = __x_parent->left;
if(__w->color == __rb_tree_red)
{
__w->color = __rb_tree_black;
__x_parent->color = __rb_tree_red;
local_Rb_tree_rotate_right(__w, __root);
__w = __x_parent->left;
}
if((__w->right == 0 ||
__w->right->color == __rb_tree_black) &&
(__w->right == 0 ||
__w->right->color == __rb_tree_black))
{
__w->color = __rb_tree_red;
__x = __x_parent;
__x_parent = __x_parent->parent;
}
else
{
if(__w->left == 0 ||
__w->left->color == __rb_tree_black)
{
__w->right->color = __rb_tree_black;
__w->color = __rb_tree_red;
local_Rb_tree_rotate_left(__w, __root);
__w = __x_parent->left;
}
__w->color = __x->parent->color;
__x->parent->color == __rb_tree_black;
if(__w->left)
{
__w->left->color = __rb_tree_black;
}
local_Rb_tree_rotate_right(__x_parent, __root);
break;
}
}
}
if(__x)
{
__x->color = __rb_tree_black;
}
}
return __y;
}
//在RB_Tree类中加入如下公有函数
void _M_erase_aux(iterator __position)
{
link_type __y =
static_cast(_Rb_tree_rebalance_for_erase
(const_cast(__position.node), this->_M_impl._M_header));
_M_drop_node(__y);
--_M_impl._M_node_count;
}
iterator erase(iterator __position)
{
iterator __result = __position;
++__result;
_M_erase_aux(__position);
return __result;
}
如果看过上一篇,那么上一篇加上这段代码就可以使用红黑树的节点删除功能。
不过我下面这里还是贴出完整代码以及运行结果:
RB_Tree头文件
/*
* RB_tree.h
*
* Created on: Jul 11, 2018
* Author: clh01s
*/
#include
#include
//#include
#include
#include
#include
#include
//#include
#include
#include
#include
#include
执行调用文件:
test.cpp
/*
* test.cpp
*
* Created on: Jul 31, 2018
* Author: clh01s
*/
#include
#include "RB_tree.h"
using namespace std;
int main()
{
RB_Tree, std::less, std::allocator> a;
cout<<"插入之前树的大小:"< rbtite;
for(auto it = a.begin();it != a.end(); ++it)
{
// rbtite = __rb_tree_base_iterator(it);
cout<<"value = "<<*it<
执行结果:
clh01s@clh01s:~/testcode/数据结构$ g++ test.cpp -std=c++11 -g
clh01s@clh01s:~/testcode/数据结构$ ./a.out
插入之前树的大小:0
插入之后树的大小:4
value = 4
value = 5
value = 6
value = 13
删除最后一个节点
删除后树的大小:3
value = 4
value = 5
value = 6
在linux系统下应该可以直接使用我的代码以及上面的编译命令编译以及运行程序。
转载请注明原地址:https://blog.csdn.net/clh01s/article/details/84339911