插入删除算法思想见上一篇文章:https://blog.csdn.net/Jodanluo/article/details/104180400
一、节点类
enum Color {RED , BLACK};
public class RBNode {
public int value;
public Color color;
public RBNode left;
public RBNode right;
public RBNode parent;
public RBNode(int value_t){
this.value = value_t;
this.color = Color.RED;
this.right = null;
this.left = null;
this.parent = null;
}
}
二、左旋和右旋
public static int Left_Rolate(RBNode Temp_Node,RBNode RBTree_head){
RBNode right_node = Temp_Node.right;
RBNode parent_node = Temp_Node.parent;
if(right_node == null)
return CommonType.failed;
Temp_Node.right = right_node.left;
if(right_node.left != null){
right_node.left.parent = Temp_Node;
}
right_node.left = Temp_Node;
Temp_Node.parent = right_node;
if(parent_node != null){
if(parent_node.left == Temp_Node){
parent_node.left = right_node;
}else{
parent_node.right = right_node;
}
}else{
RBTree_head.left = right_node;
}
right_node.parent = parent_node;
return CommonType.success;
}
public static int Right_Rolate(RBNode Temp_Node,RBNode RBTree_head){
RBNode left_node = Temp_Node.left;
RBNode parent_node = Temp_Node.parent;
if(left_node == null)
return CommonType.failed;
Temp_Node.left = left_node.right;
if(left_node.right != null){
left_node.right.parent = Temp_Node;
}
left_node.right = Temp_Node;
Temp_Node.parent = left_node.right;
if(parent_node != null){
if(parent_node.left == Temp_Node){
parent_node.left = left_node;
}else{
parent_node.right = left_node;
}
}else{
RBTree_head.left = left_node;
}
left_node.parent = parent_node;
return CommonType.success;
}
三、插入节点
public static int RBNode_Insert(RBNode RBTree_head ,RBNode Temp_Node){
//RBTree_head.left 指向根
if(Temp_Node == null){
return CommonType.failed;
}
//如果根为空,直接将当前节点置为根
if(RBTree_head.left == null){
RBTree_head.left = Temp_Node;
Temp_Node.parent = null;
Temp_Node.left = null;
Temp_Node.right = null;
Temp_Node.color = Color.BLACK;
return CommonType.success;
}
RBNode cur_node = RBTree_head.left ;
RBNode pre_node = cur_node;
//找到要插入的位置,即找到父节点(叶节点)
while(cur_node != null){
pre_node = cur_node ;
if(Temp_Node.value < cur_node.value){
cur_node = cur_node.left ;
}else{
cur_node = cur_node.right;
}
}
//判断插入左边还是右边
if(Temp_Node.value < pre_node.value ){
Temp_Node.parent = pre_node ;
pre_node.left = Temp_Node ;
}else{
Temp_Node.parent = pre_node ;
pre_node.right = Temp_Node ;
}
//如果父节点是黑色,直接插入,结束
if(pre_node.color == Color.BLACK)
return CommonType.success;
//如果父节点是红色
RBNode pre_pre_node = null;//祖父节点
RBNode pre_bro_node = null;//叔父节点
DIRECTION bro_direction = DIRECTION.LEFT;//叔父节点的方向
DIRECTION my_direction = DIRECTION.LEFT;//当前节点的方向
while(true){
pre_pre_node = pre_node.parent;
//如果父节点是黑色(包括父节点是根),结束
if( pre_node.color == Color.BLACK){
break;
}
//判断叔父节点方向
if(pre_pre_node.left == pre_node){
pre_bro_node = pre_pre_node.right;
bro_direction = DIRECTION.RIGHT;
}else{
pre_bro_node = pre_pre_node.left;
bro_direction = DIRECTION.LEFT;
}
//判断当前节点方向
if(pre_node.left == Temp_Node){
my_direction = DIRECTION.LEFT;
}else{
my_direction = DIRECTION.RIGHT;
}
if(pre_bro_node == null || pre_bro_node.color == Color.BLACK){
//叔父节点为黑或空 的四种情况
if(bro_direction == DIRECTION.LEFT && my_direction == DIRECTION.RIGHT){
pre_node.color = Color.BLACK;
pre_pre_node.color = Color.RED;
Left_Rolate(pre_pre_node,RBTree_head);//左旋
}else if(bro_direction == DIRECTION.LEFT && my_direction == DIRECTION.LEFT){
Right_Rolate(pre_node,RBTree_head);//右旋
Temp_Node.color = Color.BLACK;
pre_pre_node.color = Color.RED;
Left_Rolate(pre_pre_node,RBTree_head);
}else if(bro_direction == DIRECTION.RIGHT && my_direction == DIRECTION.LEFT){
pre_node.color = Color.BLACK;
pre_pre_node.color = Color.RED;
Right_Rolate(pre_node,RBTree_head);
}else{
Left_Rolate(pre_node,RBTree_head);
Temp_Node.color = Color.BLACK;
pre_pre_node.color = Color.RED;
Right_Rolate(pre_pre_node,RBTree_head);
}
break;
}else{
//叔父节点为红的情况
pre_node.color = Color.BLACK;
pre_bro_node.color = Color.BLACK;
pre_pre_node.color = Color.RED;
Temp_Node = pre_pre_node;
pre_node = Temp_Node.parent;
//如果当前节点是根,结束
if(pre_node == null){
Temp_Node.color = Color.BLACK;
break;
}
}
}
return CommonType.success;
}
四、删除节点
public static int RBNode_Delete(RBNode RBTree_head ,int value_t){
if(RBTree_head.left == null){
return CommonType.failed;
}
//找到要删除的节点
RBNode temp_node = search_delete_node(RBTree_head, value_t);
if(temp_node == null){
System.out.println("the num is not exit!!");
return CommonType.failed;
}
//如果节点有两个孩子,则转换为单孩子节点或叶子节点
if(temp_node.left != null && temp_node.right != null){
RBNode leaf_node = convert_to_leaf(temp_node);
if(leaf_node == null)
return CommonType.failed;
int value_s = leaf_node.value;
leaf_node.value = temp_node.value;
temp_node.value = value_s;
temp_node = leaf_node;
}
//如果节点有单孩子
if(temp_node.left != null){
RBNode real_leaf_node = temp_node.left;
int value_s = real_leaf_node.value;
real_leaf_node.value = temp_node.value;
temp_node.value = value_s;
temp_node = real_leaf_node;
}else if(temp_node.right != null){
RBNode real_leaf_node = temp_node.right;
int value_s = real_leaf_node.value;
real_leaf_node.value = temp_node.value;
temp_node.value = value_s;
temp_node = real_leaf_node;
}
RBNode parent_node = temp_node.parent;
//如果要删除的节点是根
if(parent_node == null){
RBTree_head.left = null;
return CommonType.success;
}
//如果要删除的节点是红色
if(temp_node.color == Color.RED){
if(parent_node.left == temp_node){
parent_node.left = null;
}else{
parent_node.right = null;
}
return CommonType.success;
}
//如果要删除的节点是黑色,则先进行删除再进行平衡调整
RBNode bro_node = null;//兄弟节点
DIRECTION bro_dir = DIRECTION.LEFT;
if(parent_node.left == temp_node){
bro_node = parent_node.right;
parent_node.left = null;
bro_dir = DIRECTION.RIGHT;
}else{
bro_node = parent_node.left;
parent_node.right = null;
}
//平衡调整过程
while(true){
if(bro_node.color == Color.RED){//兄弟节点一定不为空
//如果兄弟节点是红色,调整兄弟节点和父节点的颜色,再进行右旋或者左旋,并更新引用做下一轮判断,父节点引用不用更新,兄弟节点引用要更新
bro_node.color = Color.BLACK;
parent_node.color = Color.RED;
if(bro_dir == DIRECTION.LEFT){
Right_Rolate(parent_node,RBTree_head);
bro_node = parent_node.left;
bro_dir = DIRECTION.LEFT;
}else{
Left_Rolate(parent_node,RBTree_head);
bro_node = parent_node.right;
bro_dir = DIRECTION.RIGHT;
}
}else{
//如果兄弟节点是黑色,则判断远近侄子是否为红
//condition 取3为远近侄子都为黑或者空的情况;取2为右侄子为远侄子,远侄子颜色为红的情况;取1为左侄子为远侄子,远侄子颜色为红的情况;
int condition = 0 ;
//pre_condition 取1为左侄子为红右侄子为黑(空),但左侄子为近侄子的情况;取2为右侄子为红左侄子为黑(空),但右侄子为近侄子的情况;
int pre_condition = 0 ;
RBNode bro_left_node = bro_node.left;//左侄子
RBNode bro_right_node = bro_node.right;//右侄子
if(bro_left_node == null && bro_right_node == null){
//3.1
condition = 3;
}else if(bro_left_node != null && bro_right_node == null){
if(bro_left_node.color == Color.RED){
if(bro_dir == DIRECTION.LEFT){
//1.1
condition = 1;
}else{
//2.1-1.2
pre_condition = 1;
}
}else{
//3.1
condition = 3;
}
}else if(bro_left_node == null && bro_right_node != null){
if(bro_right_node.color == Color.RED){
if(bro_dir == DIRECTION.RIGHT){
//1.2
condition = 2;
}else{
//2.2-1.1
pre_condition = 2;
}
}else{
//3.1
condition = 3;
}
}else{
if(bro_left_node.color == Color.BLACK && bro_right_node.color == Color.BLACK){
//3.1
condition = 3;
}else{
if(bro_dir == DIRECTION.LEFT){
if(bro_left_node.color == Color.RED){
//1.1
condition = 1;
}else{
//2.2-1.1
pre_condition = 2;
}
}else{
if(bro_right_node.color == Color.RED){
//1.2
condition = 2;
}else{
//2.1->1.2
pre_condition = 1;
}
}
}
}
if(pre_condition == 2){
//右侄子为红且为近侄子时,需要调换右侄子和兄弟节点颜色,并对兄弟节点进行左旋,转换为conditon为1的情况
bro_node.color = Color.RED;
bro_right_node.color = Color.BLACK;
Left_Rolate(bro_node,RBTree_head);
condition = 1;
}else if(pre_condition == 1){
//左侄子为红且为近侄子时,需要调换左侄子和兄弟节点颜色,并对兄弟节点进行右旋,转换为conditon为2的情况
bro_node.color = Color.RED;
bro_left_node.color = Color.BLACK;
Right_Rolate(bro_node,RBTree_head);
condition = 2;
}
if(condition == 3){
//远近侄子节点为黑色或者空的情况
if(parent_node.color == Color.RED){
//父节点为红
bro_node.color = Color.RED;
parent_node.color = Color.BLACK;
break;
}else{
//父节点为黑
bro_node.color = Color.RED;
if(parent_node.parent == null){
//父节点为根,结束调整
parent_node.color = Color.BLACK;
break;
}
//准备做下一轮判断,更新引用和方向
if(parent_node.parent.left == parent_node){
bro_node = parent_node.parent.right;
parent_node = parent_node.parent;
bro_dir = DIRECTION.RIGHT;
}else{
bro_node = parent_node.parent.left;
parent_node = parent_node.parent;
bro_dir = DIRECTION.LEFT;
}
}
}else if(condition == 2){
//右侄子为远侄子且颜色为红时,兄弟节点取父节点颜色,父节点和远侄子取黑色,再对父节点进行左旋,结束
bro_node.color = parent_node.color;
parent_node.color = Color.BLACK;
bro_right_node.color = Color.BLACK;
Left_Rolate( parent_node,RBTree_head);
break;
}else if(condition == 1){
//左侄子为远侄子且颜色为红时,兄弟节点取父节点颜色,父节点和远侄子取黑色,再对父节点进行右旋,结束
bro_node.color = parent_node.color;
parent_node.color = Color.BLACK;
bro_left_node.color = Color.BLACK;
Right_Rolate( parent_node,RBTree_head);
break;
}
}
}
return CommonType.success;
}
五、其他相关函数
public static RBNode search_delete_node(RBNode RBTree_head , int value_t){
RBNode temp_node = RBTree_head.left ;
while(temp_node != null){
if(value_t < temp_node.value){
temp_node = temp_node.left;
}else if(value_t > temp_node.value){
temp_node = temp_node.right;
}else{
return temp_node;
}
}
return null;
}
public static RBNode convert_to_leaf(RBNode temp_node){
if(temp_node == null)
return null;
RBNode search_node = temp_node.right;
while(search_node != null){
if(search_node.left != null){
search_node = search_node.left;
}else{
return search_node;
}
}
return null;
}