红黑树插入删除算法——java代码实现

插入删除算法思想见上一篇文章: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;
     }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.算法是程序的灵魂,优秀的程序在对海量数据处理时,依然保持高速计算,就需要高效的数据结构算法支撑。2.网上数据结构算法的课程不少,但存在两个问题:1)授课方式单一,大多是照着代码念一遍,数据结构算法本身就比较难理解,对基础好的学员来说,还好一点,对基础不好的学生来说,基本上就是听天书了2)说是讲数据结构算法,但大多是挂羊头卖狗肉,算法讲的很少。 本课程针对上述问题,有针对性的进行了升级 3)授课方式采用图解+算法游戏的方式,让课程生动有趣好理解 4)系统全面的讲解了数据结构算法, 除常用数据结构算法外,还包括程序员常用10大算法:二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、马踏棋盘算法。可以解决面试遇到的最短路径、最小生成树、最小连通图、动态规划等问题及衍生出的面试题,让你秒杀其他面试小伙伴3.如果你不想永远都是代码工人,就需要花时间来研究下数据结构算法。教程内容:本教程是使用Java来讲解数据结构算法,考虑到数据结构算法较难,授课采用图解加算法游戏的方式。内容包括: 稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫问题、栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式、递归与回溯、迷宫问题、八皇后问题、算法的时间复杂度、冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、基数排序(桶排序)、堆排序、排序速度分析、二分查找、插值查找、斐波那契查找、散列、哈希表、二叉树、二叉树与数组转换、二叉排序树(BST)、AVL树、线索二叉树、赫夫曼树、赫夫曼编码、多路查找树(B树B+树和B*树)、图、图的DFS算法和BFS、程序员常用10大算法、二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法马踏棋盘算法。学习目标:通过学习,学员能掌握主流数据结构算法实现机制,开阔编程思路,提高优化程序的能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值