红黑树的底层实现(java实现)

 

一、红黑树的介绍

红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的二叉查找树。
红黑树是特殊的二叉查找树,意味着它满足二叉查找树的特征:任意一个节点所包含的键值,大于等于左孩子的键值,小于等于右孩子的键值。
除了具备该特性之外,红黑树还包括许多额外的信息。

红黑树的每个节点上都有存储位表示节点的颜色,颜色是红(Red)或黑(Black)。
红黑树的特性:
(1) 每个节点或者是黑色,或者是红色。
(2) 根节点是黑色。
(3) 每个叶子节点是黑色。 [注意:这里叶子节点,是指为空的叶子节点!]
(4) 如果一个节点是红色的,则它的子节点必须是黑色的。
(5) 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

 二、红黑树的基础

    本文黑色叶子空节点没有添加,如需添加照着改即可,感觉黑色的叶子空节点删除的时候用到,便于理解。

   (1)、基础操作左旋右旋

       a、左旋操作

    

       b、右旋操作

          

   (2)红黑树的基础代码如下:

      

public class RedBlackTree<T extends Comparable<T>> {
    
    
    
    
     class Node {
         T t;
         Node parent;
         Node left;
         Node right;
         Color color;
        public Node(T t, Node parent,Node left,Node right,
                Color color) {
            super();
            this.t = t;
            this.parent = parent;
            this.left = left;
            this.right = right;
            this.color = color;
        }
        
        public void setColor(Color color) {
            this.color=color;
        }
        
    }
    
    private enum Color{
        Red,
        Black,
    }
    
    Node root;
    Node nil=new Node(null,null,null,null,Color.Black);
    
    /*
     * 获取祖父节点
     */
    public Node getGrandParent(Node node) {
        if(node.parent==null) {
            return null;
        }
        return node.parent.parent;
    }
    
    /*
     * 获取当前节点的叔节点
     */
    public Node getUncle(Node node) {
        Node grandParent=getGrandParent(node);
        if(grandParent==null) {
            return null;
        }
        if(node.parent==grandParent.left) {
            return grandParent.right;
        }else {
            return grandParent.left;
        }
    }
    /*                    x   
     *        
     *               a       y
     *               
     *                     b     z
     */
    //左旋
    public Node leftRotate(Node x) {
        Node y=x.right;
        Node b=y.left;
        x.right=b;
        y.left=x;
        
        x.parent=y;        
        if(b!=null) {
            b.parent=x;

        }
        
        return y;
    }
    /*            x
     * 
     *     y        a
     * 
     * z     b
     */
    //右旋
    public Node rightRotate(Node x) {
        Node y=x.left;
        Node b=y.right;
        
        x.left=b;
        y.right=x;
        
        x.parent=y;
        if(b!=null) {
            b.parent=x;

        }
        

        return y;
    }
    
    /*
     * 前序遍历
     */
    public void preTraversal(Node current) {
        if(current!=null) {
            System.out.println(current.t+" "+current.color);
            preTraversal(current.left);
            preTraversal(current.right);
        }
    }


}

三、红黑树的新增

    新增节点肯定是红色,如果是黑色就破坏了性质5,黑色节点数量就增加,就必须进行平衡操作,红色节点不会新增黑色节点数量。

 1、新增节点几种类型

   (1)、当新增节点父节点是黑色,直接插入、不会破坏树的平衡

          

   (2)、当新增节点父节点是红色,叔节点是红色,破坏性质4,不能出现连续的红节点,需要平衡操作

        

   (3)、当新增节点父节点是红色,叔节点不存在或者为黑色(叔节点肯定不为黑色,如果是黑色,破坏了性质5),还是破坏性质4,需要平衡操作

      (a)、当父节点是祖父节点左孩子,且新增节点是父节点左孩子,先变色,在右旋

             

      (b)、当父节点是祖父节点的左孩子,新增节点是父节点右孩子

              

      (c)、当父节点是祖父节点右孩子、新增节点是父节点右孩子

              

       (d)、当父节点是祖父节点右孩子,新增节点是父节点的左孩子

              

2、新增节点代码   

    public void addNode(Node current,T t) {

        Node node=current;
        Node parent = null;
        boolean isLeft=true;
        while(node!=null) {
            if(t.compareTo(node.t)<0) {
                isLeft=true;
                parent=node;
                node=node.left;
            }else if(t.compareTo(node.t)>0) {
                isLeft=false;
                parent=node;
                node=node.right;
            }
            
        }
        if(node==null&&parent==null) {
            root=new Node(t,null,null,null,Color.Black);
        }else if(node==null&&parent!=null) {
            Node newNode=new Node(t,null,null,null,Color.Red);
            newNode.parent=parent;
            if(isLeft) {
                parent.left=newNode;
            }else {
                parent.right=newNode;
            }
            setBalance(newNode);
        }
        
    }

  3、平衡操作

    

//使红黑树保持平衡  新增平衡调整
    public void setBalance(Node node) {
        Node current=node;
        Node grandparent;
        Node uncle;
        
        while(current.parent!=null&&current.parent.color==Color.Red) {
                grandparent=getGrandParent(current);
                uncle=getUncle(current);
                //父节点是祖父节点的左孩子L
                if(grandparent.left==current.parent) {
                        //叔节点存在  且为红
                        if(uncle!=null&&uncle.color==Color.Red) {
                            uncle.color=Color.Black;
                            current.parent.color=Color.Black;
                            grandparent.color=Color.Red;
                            current=grandparent;
                        }else {//叔节点不存在或者为黑   LL //只旋转一次 要变色    
                            if(current.parent.left==current) {
                                 Node gpp=grandparent.parent;//祖父节点的父节点
                                 grandparent.color=Color.Red;
                                 current.color=Color.Red;
                                 current.parent.color=Color.Black;
                                 if(gpp!=null&&gpp.left==grandparent) {
                                     gpp.left=rightRotate(grandparent);
                                     
                                 }else if(gpp!=null&&gpp.right==grandparent) {

                                     gpp.right=rightRotate(grandparent);
                                 }else {                                 
                                    root= rightRotate(grandparent);
                                     
                                 }
                                 
                            }else {//LR
                                 Node gpp=grandparent.parent;//祖父节点的父节点
                                 grandparent.left=leftRotate(current.parent);
                                 //先变色在旋转
                                 grandparent.left.color=Color.Black;
                                 current.color=Color.Red;
                                 grandparent.color=Color.Red;
                                 
                                 if(gpp!=null&&gpp.left==grandparent) {

                                     gpp.left=rightRotate(grandparent);
                                 }else if(gpp!=null&&gpp.right==grandparent) {
                                     gpp.right=rightRotate(grandparent);

                                 }else {
                                     root=rightRotate(grandparent);
                                 }
                            }
                        }
                }else {//R
                    //叔节点存在  且为红
                    if(uncle!=null&&uncle.color==Color.Red) {
                        uncle.color=Color.Black;
                        current.parent.color=Color.Black;
                        grandparent.color=Color.Red;
                        current=grandparent;
                    }else {//叔节点不存在或者为黑
                        if(current.parent.left==current) {//RL
                             Node gpp=grandparent.parent;//祖父节点的父节点
                             grandparent.right=rightRotate(current.parent);
                             //先变色在旋转
                             grandparent.right.color=Color.Black;
                             current.color=Color.Red;
                             grandparent.color=Color.Red;
                             if(gpp!=null&&gpp.left==grandparent) {
                                 gpp.left=leftRotate(grandparent);
                             }else if(gpp!=null&&gpp.right==grandparent) {
                                 gpp.right=leftRotate(grandparent);
                             }else {
                                root= leftRotate(grandparent);
                             }
                             
                        }else {//RR  
                             Node gpp=grandparent.parent;//祖父节点的父节点
                             grandparent.color=Color.Red;
                             current.color=Color.Red;
                             current.parent.color=Color.Black;
                             if(gpp!=null&&gpp.left==grandparent) {

                                 gpp.left=leftRotate(grandparent);
                                 
                             }else if(gpp!=null&&gpp.right==grandparent) {

                                 gpp.right=leftRotate(grandparent);
                             }else {                                 
                                root= leftRotate(grandparent);
                                 
                             }
                        }
                    }
                    
                }
        }
        
        
        root.color=Color.Black;


    }

三、红黑树的删除

 1、删除存在的几种场景 

   (1)、被删节点是红色 

      (a)、红色是叶子节点、直接删除

               

       (b)、红色节点存在两个孩子(不可能存在一个孩子),找打替代节点,

        替代节点为红色:只能为红色叶子节点,替代节点替换被删节点,删掉替代节点(以前驱节点为列)

                  

   替代节点为黑色:(可能是黑色叶子节点或者替换节点(前驱不存在右孩子的)存在一个红色左孩子),先平衡替换节点,替换节点替换被删节点,再删除替换节点。

   平衡操作:替代节点的父节点是红色,父节点变黑、兄弟节点变红,然后进行替换节点替换被删节点,删除替换节点.(先平衡后替换,最后删除)

                  

 (2)、被删节点是黑色(部分需要平衡操作,下面平衡的步骤详解)

     (a)、被删节点是黑色叶子节点,需要平衡操作
     (b)、存在替代节点,且为黑色,先平衡操作,在删除替代节点,替代节点和被删节点替换。
      (c)、替代节点是红色(只能是红色的叶子节点,负责不满足平衡树),直接删除替代节点,替代节点与被删节点替换即可

                  

  

2、平衡的步骤(先平衡替换节点,删除替换节点,在把替换节点替换被删节点)

     平衡操作:
      兄弟节点是红色,则父节点、兄弟节点的孩子一定是黑色,变色 左旋或者右旋
      父节点是红色,兄弟节点不存在孩子,父节点变黑、兄弟节点变红
      兄弟节点是黑色、兄弟节点孩子不存在、或者都为黑色、父节点也是黑色,兄弟节点变红色,父节点为当前节点进行递归操作
      兄弟节点是黑色、兄弟节点的左孩子或者右孩子为红色,一般旋转变色

 (1)兄弟节点是红色 

     (a)、替换节点是父节点的左孩子,即兄弟节点是右孩子,需要p变红、s变黑,进行左旋得到下面(c)。(每个分支黑色节点数量不变,x最后是要被删除的)

              

      (b)、替换节点是父节点的右孩子,即兄弟节点是左孩子,rn变红、s变黑,对gp右旋(操作同a,简化了中间的步骤) 。 

                      

        

 (2)兄弟节点是黑色

   (c)替换节点父节点是红色,切兄弟节点不存在孩子

                        

    (d)替换节点父节点是黑色、兄弟节点的两个孩子不存在(默认两个黑色空节点)或者存在两个黑色的子节点。

        此次兄弟子树都没红结点“借”了,兄弟帮忙不了,找父母呗,这种情景我们把兄弟结点设为红色,再把父结点当作替代结点,自底向上处理,去找父结点的兄弟结点去“借”。但为什么需要把兄弟结点设为红色呢?                           显然是为了在P所在的子树中保证平衡(X即将删除,少了一个黑色结点,子树也需要少一个),后续的平衡工作交给父辈们考虑了,当每棵子树都保持平衡时,最终整棵总是平衡的。

        

  (e)、替换节点为父节点左孩子,

    兄弟节点存在右孩子为红色

    删除的左子树的一个黑色结点,显然左子树的黑色结点少1了,然而右子树又又红色结点,那么我们直接向右子树“借”个红结点来补充黑结点就好啦,此时肯定需要用旋转处理了

         

   兄弟节点不存在右孩子,存在左孩子为红(主要就是子树到达平衡,即黑色节点数量,第一步先转换成右孩子,就可以左旋)

      

 (f)替换节点为父节点右孩子

       兄弟节点存在左孩子且为红色

      

      兄弟节点不存在左孩子或者左孩子不为红,右孩子为红

                                 

    (3)删除的源代码

    

    public void delete(T t) {
        /*
         * 找到被删除节点
         */
        Node delNode = null,replaceNode = null;//被删节点  替代节点
        Node tmp=root;
        while(tmp!=null) {
            if(t.compareTo(tmp.t)<0) {
                tmp=tmp.left;
            }else if(t.compareTo(tmp.t)>0) {
                tmp=tmp.right;
            }else {
                delNode=tmp;
                break;
            }
        }
        
        if(null!=delNode&&delNode.color==Color.Red) {//待删除节点是红色
            
            if(delNode.left!=null&&delNode.right!=null) {
                replaceNode=getReplaceNode(delNode);
                delBalace(replaceNode);
                if(delNode.left!=replaceNode) {//不等于删除替换节点,等于时,替换掉之后相当于删除
                    deleteNode(delNode.left,replaceNode.t);

                }
                if(delNode==delNode.parent.left) {
                    delNode.parent.left=replaceNode;
                    if(replaceNode!=delNode.left) {
                        replaceNode.left=delNode.left;

                    }                
                    replaceNode.right=delNode.right;
                }else {
                    delNode.parent.right=replaceNode;
                    if(replaceNode!=delNode.left) {
                        replaceNode.left=delNode.left;
                    }                    
                    replaceNode.right=delNode.right;
                }

            }else {
                deleteNode(root,t);
            }
        }else {
            replaceNode=getReplaceNode(delNode);
            if(replaceNode==null) {
                if(delNode!=root) {
                    delBalace(delNode);
                }
                deleteNode(root,delNode.t);

            }else if(replaceNode.color==Color.Black) {
                delBalace(replaceNode);
                deleteNode(delNode,replaceNode.t);
                replaceNode.color=delNode.color;
                if(delNode==root) {
                     return;
                }
                if(delNode==delNode.parent.left) {
                    delNode.parent.left=replaceNode;
                    if(replaceNode!=delNode.left) {
                        replaceNode.left=delNode.left;
                    }                    
                    replaceNode.right=delNode.right;
                }else {
                    delNode.parent.right=replaceNode;
                    if(replaceNode==delNode.left) {
                        replaceNode.left=null;

                    }else {
                        replaceNode.left=delNode.left;
                    }                    
                    replaceNode.right=delNode.right;
                }
            }else {//直接执行删除操作
                
                replaceNode.color=delNode.color;
                deleteNode(delNode.t);
                if(delNode.parent==null) {//root节点
                    replaceNode.left=delNode.left;
                    replaceNode.right=delNode.right;
                }else {
                    if(delNode==delNode.parent.left) {
                        delNode.parent.left=replaceNode;
                        if(replaceNode==delNode.left) {
                            replaceNode.left=null;

                        }else {
                            replaceNode.left=delNode.left;
                        }                    
                        replaceNode.right=delNode.right;
                    }else {
                        delNode.parent.right=replaceNode;
                        if(replaceNode==delNode.left) {
                            replaceNode.left=null;

                        }else {
                            replaceNode.left=delNode.left;
                        }
                        replaceNode.right=delNode.right;
                    }                
                }

            }
        }

        
    }    

    
    
    public void deleteNode(T t) {
        if(t!=null) {
            root=deleteNode(root,t);
        }
    }
    //删除节点
    public Node deleteNode(Node node,T t) {
        
        if(t.compareTo(node.t)<0) {
            node.left=deleteNode(node.left,t);
        }else if(t.compareTo(node.t)>0) {
            node.right=deleteNode(node.right,t);
        }else {
            if(node.left==null&&node.right==null) {
                return null;
            }
            
            if(node.left==null&&node.right!=null) {
                return node.right;
            }else if(node.left!=null&&node.right==null) {
                return node.left;
            }
            
            if(node.left!=null&&node.right!=null) {
                  Node preNode=getReplaceNode(node);
                  preNode.left=deleteNode(node.left,preNode.t);
                  preNode.right=node.right;
                  return preNode;
            }
        }
        return node;
    }
    //删除平衡操作
    public void delBalace(Node current) {
        Node parent=current.parent;
        Node gp=parent.parent;
        Node s=parent.left==current?parent.right:parent.left;//兄弟节点
        Node ln=s.left;//兄弟节点左孩子
        Node rn=s.right;//兄弟节点右孩子
        //case 1
        if(s.color==Color.Red) {
            if(current==current.parent.left) {
                /*                      p black                                 s black
                 *                                           左旋 变色
                 *              x black       s red        ---->       p   black       rn   black
                 *  
                 *                        ln black  rn black       x     ln red
                 */
                //旋转前先变色,
                s.color=Color.Black;
                ln.color=Color.Red;
                if(gp==null) {
                     root=leftRotate(parent);

                }else if(gp.left==parent) {
                    gp.left=leftRotate(parent);
                }else if(gp.right==parent){
                    gp.right=leftRotate(parent);
                }
            }else {
                /*                    p black                           s  black 
                 *                                         右旋变色      
                 *             s  red         x  black     --->                     ln  black    p   black
                 * 
                 *    ln black   rn black                                                  rn red   x
                 * 
                 */
                s.color=Color.Black;
                rn.color=Color.Red;
                if(gp==null) {
                     root=rightRotate(parent);

                }else if(gp.left==parent) {
                    gp.left=rightRotate(parent);
                }else if(gp.right==parent){
                    gp.right=rightRotate(parent);
                }
            }

            
        }else {
            if((ln==null&&rn==null&&parent.color==Color.Black)
                    ||(ln.color==Color.Black&&rn.color==Color.Black&&parent.color==Color.Black)) {
                 s.color=Color.Red;
                 current=parent;
                 delBalace(current);//递归调用
            }else if(parent.color==Color.Red&&ln==null&&rn==null){
                /*           p red                                        p black
                 * 
                 *      x black     s black      --->             x black     s red 
                 */
                s.color=Color.Red;
                parent.color=Color.Black;
                
            }else if(rn!=null&&rn.color==Color.Red) {//  rn  为red
                if(current==parent.left) {//被删节点是左孩子
                     s.color=parent.color;
                     parent.color=Color.Black;
                     rn.color=Color.Black;
                     if(gp==null) {
                         root=leftRotate(parent);
                     }else     if(gp.left==parent) {
                         gp.left=leftRotate(parent);
                     }else if(gp.right==parent) {
                         gp.right=leftRotate(parent);
                     }
                }else {//Lr
                    /*            p                                p                             rn(p 的颜色)
                     * 
                     *     s black   x black    --->    rn            x     -->        s black           p black
                     * 
                     *        rn red                s                                                       x
                     */
                     rn.color=parent.color;
                     parent.color=Color.Black;
                     parent.left=leftRotate(s);
                     if(gp==null) {
                         root=rightRotate(parent);
                     }else if(gp.left==parent) {
                         gp.left=rightRotate(parent);
                     }else if(gp.right==parent) {
                         gp.right=rightRotate(parent);
                     }
                }
                 return ;
            }else if(ln!=null&&ln.color==Color.Red) {
                    if(current==parent.left) {
                        parent.right=rightRotate(s);
                        ln.color=parent.color;
                        parent.color=Color.Black;
                        if(gp==null) {
                             root=leftRotate(parent);
                         }else if(gp.left==parent) {
                             gp.left=leftRotate(parent);
                         }else if(gp.right==parent) {
                             gp.right=leftRotate(parent);
                         }
                    }else {
                         s.color=parent.color;
                         parent.color=Color.Black;
                         ln.color=Color.Black;
                         if(gp==null) {
                             root=rightRotate(parent);
                         }else     if(gp.left==parent) {
                             gp.left=rightRotate(parent);
                         }else if(gp.right==parent) {
                             gp.right=rightRotate(parent);
                         }

                    }
            }
            
            
        }
    }

四、全部源代码

  

package com.binarytree;

public class RedBlackTree<T extends Comparable<T>> {
    
    
    
    
     class Node {
         T t;
         Node parent;
         Node left;
         Node right;
         Color color;
        public Node(T t, Node parent,Node left,Node right,
                Color color) {
            super();
            this.t = t;
            this.parent = parent;
            this.left = left;
            this.right = right;
            this.color = color;
        }
        
        public void setColor(Color color) {
            this.color=color;
        }
        
    }
    
    private enum Color{
        Red,
        Black,
    }
    
    Node root;
    Node nil=new Node(null,null,null,null,Color.Black);
    
    /*
     * 获取祖父节点
     */
    public Node getGrandParent(Node node) {
        if(node.parent==null) {
            return null;
        }
        return node.parent.parent;
    }
    
    /*
     * 获取当前节点的叔节点
     */
    public Node getUncle(Node node) {
        Node grandParent=getGrandParent(node);
        if(grandParent==null) {
            return null;
        }
        if(node.parent==grandParent.left) {
            return grandParent.right;
        }else {
            return grandParent.left;
        }
    }
    /*                    x   
     *        
     *               a       y
     *               
     *                     b     z
     */
    //左旋
    public Node leftRotate(Node x) {
        Node y=x.right;
        Node b=y.left;
        x.right=b;
        y.left=x;
        
        x.parent=y;        
        if(b!=null) {
            b.parent=x;

        }
        
        return y;
    }
    /*            x
     * 
     *     y        a
     * 
     * z     b
     */
    //右旋
    public Node rightRotate(Node x) {
        Node y=x.left;
        Node b=y.right;
        
        x.left=b;
        y.right=x;
        
        x.parent=y;
        if(b!=null) {
            b.parent=x;

        }
        

        return y;
    }
    
    public void addNode(T t) {
        if(t!=null) {
            addNode(root,t);
        }
    }
    
    public void addNode(Node current,T t) {

        Node node=current;
        Node parent = null;
        boolean isLeft=true;
        while(node!=null) {
            if(t.compareTo(node.t)<0) {
                isLeft=true;
                parent=node;
                node=node.left;
            }else if(t.compareTo(node.t)>0) {
                isLeft=false;
                parent=node;
                node=node.right;
            }
            
        }
        if(node==null&&parent==null) {
            root=new Node(t,null,null,null,Color.Black);
        }else if(node==null&&parent!=null) {
            Node newNode=new Node(t,null,null,null,Color.Red);
            newNode.parent=parent;
            if(isLeft) {
                parent.left=newNode;
            }else {
                parent.right=newNode;
            }
            setBalance(newNode);
        }
        
    }
    
    
    //使红黑树保持平衡  新增平衡调整
    public void setBalance(Node node) {
        Node current=node;
        Node grandparent;
        Node uncle;
        
        while(current.parent!=null&&current.parent.color==Color.Red) {
                grandparent=getGrandParent(current);
                uncle=getUncle(current);
                //父节点是祖父节点的左孩子L
                if(grandparent.left==current.parent) {
                        //叔节点存在  且为红
                        if(uncle!=null&&uncle.color==Color.Red) {
                            uncle.color=Color.Black;
                            current.parent.color=Color.Black;
                            grandparent.color=Color.Red;
                            current=grandparent;
                        }else {//叔节点不存在或者为黑   LL //只旋转一次 要变色    
                            if(current.parent.left==current) {
                                 Node gpp=grandparent.parent;//祖父节点的父节点
                                 grandparent.color=Color.Red;
                                 current.color=Color.Red;
                                 current.parent.color=Color.Black;
                                 if(gpp!=null&&gpp.left==grandparent) {
                                     gpp.left=rightRotate(grandparent);
                                     
                                 }else if(gpp!=null&&gpp.right==grandparent) {

                                     gpp.right=rightRotate(grandparent);
                                 }else {                                 
                                    root= rightRotate(grandparent);
                                     
                                 }
                                 
                            }else {//LR
                                 Node gpp=grandparent.parent;//祖父节点的父节点
                                 grandparent.left=leftRotate(current.parent);
                                 //先变色在旋转
                                 grandparent.left.color=Color.Black;
                                 current.color=Color.Red;
                                 grandparent.color=Color.Red;
                                 
                                 if(gpp!=null&&gpp.left==grandparent) {

                                     gpp.left=rightRotate(grandparent);
                                 }else if(gpp!=null&&gpp.right==grandparent) {
                                     gpp.right=rightRotate(grandparent);

                                 }else {
                                     root=rightRotate(grandparent);
                                 }
                            }
                        }
                }else {//R
                    //叔节点存在  且为红
                    if(uncle!=null&&uncle.color==Color.Red) {
                        uncle.color=Color.Black;
                        current.parent.color=Color.Black;
                        grandparent.color=Color.Red;
                        current=grandparent;
                    }else {//叔节点不存在或者为黑
                        if(current.parent.left==current) {//RL
                             Node gpp=grandparent.parent;//祖父节点的父节点
                             grandparent.right=rightRotate(current.parent);
                             //先变色在旋转
                             grandparent.right.color=Color.Black;
                             current.color=Color.Red;
                             grandparent.color=Color.Red;
                             if(gpp!=null&&gpp.left==grandparent) {
                                 gpp.left=leftRotate(grandparent);
                             }else if(gpp!=null&&gpp.right==grandparent) {
                                 gpp.right=leftRotate(grandparent);
                             }else {
                                root= leftRotate(grandparent);
                             }
                             
                        }else {//RR  
                             Node gpp=grandparent.parent;//祖父节点的父节点
                             grandparent.color=Color.Red;
                             current.color=Color.Red;
                             current.parent.color=Color.Black;
                             if(gpp!=null&&gpp.left==grandparent) {

                                 gpp.left=leftRotate(grandparent);
                                 
                             }else if(gpp!=null&&gpp.right==grandparent) {

                                 gpp.right=leftRotate(grandparent);
                             }else {                                 
                                root= leftRotate(grandparent);
                                 
                             }
                        }
                    }
                    
                }
        }
        
        
        root.color=Color.Black;


    }
    
    
    
    public Node getReplaceNode(Node node) {
        if(node.left!=null&&node.right!=null) {//获取前驱节点
            Node tmp=node.left;
            while(tmp.right!=null) {
                tmp=tmp.right;
            }
            return tmp;
        }
        
        if(node.left==null&&node.right==null) {
            return null;
        }
        return node.left==null?node.right:node.left;
    }
    
    
    public void delete(T t) {
        /*
         * 找到被删除节点
         */
        Node delNode = null,replaceNode = null;//被删节点  替代节点
        Node tmp=root;
        while(tmp!=null) {
            if(t.compareTo(tmp.t)<0) {
                tmp=tmp.left;
            }else if(t.compareTo(tmp.t)>0) {
                tmp=tmp.right;
            }else {
                delNode=tmp;
                break;
            }
        }
        
        if(null!=delNode&&delNode.color==Color.Red) {//待删除节点是红色
            
            if(delNode.left!=null&&delNode.right!=null) {
                replaceNode=getReplaceNode(delNode);
                delBalace(replaceNode);
                if(delNode.left!=replaceNode) {//不等于删除替换节点,等于时,替换掉之后相当于删除
                    deleteNode(delNode.left,replaceNode.t);

                }
                if(delNode==delNode.parent.left) {
                    delNode.parent.left=replaceNode;
                    if(replaceNode!=delNode.left) {
                        replaceNode.left=delNode.left;

                    }                
                    replaceNode.right=delNode.right;
                }else {
                    delNode.parent.right=replaceNode;
                    if(replaceNode!=delNode.left) {
                        replaceNode.left=delNode.left;
                    }                    
                    replaceNode.right=delNode.right;
                }

            }else {
                deleteNode(root,t);
            }
        }else {
            replaceNode=getReplaceNode(delNode);
            if(replaceNode==null) {
                if(delNode!=root) {
                    delBalace(delNode);
                }
                deleteNode(root,delNode.t);

            }else if(replaceNode.color==Color.Black) {
                delBalace(replaceNode);
                deleteNode(delNode,replaceNode.t);
                replaceNode.color=delNode.color;
                if(delNode==root) {
                     return;
                }
                if(delNode==delNode.parent.left) {
                    delNode.parent.left=replaceNode;
                    if(replaceNode!=delNode.left) {
                        replaceNode.left=delNode.left;
                    }                    
                    replaceNode.right=delNode.right;
                }else {
                    delNode.parent.right=replaceNode;
                    if(replaceNode==delNode.left) {
                        replaceNode.left=null;

                    }else {
                        replaceNode.left=delNode.left;
                    }                    
                    replaceNode.right=delNode.right;
                }
            }else {//直接执行删除操作
                
                replaceNode.color=delNode.color;
                deleteNode(delNode.t);
                if(delNode.parent==null) {//root节点
                    replaceNode.left=delNode.left;
                    replaceNode.right=delNode.right;
                }else {
                    if(delNode==delNode.parent.left) {
                        delNode.parent.left=replaceNode;
                        if(replaceNode==delNode.left) {
                            replaceNode.left=null;

                        }else {
                            replaceNode.left=delNode.left;
                        }                    
                        replaceNode.right=delNode.right;
                    }else {
                        delNode.parent.right=replaceNode;
                        if(replaceNode==delNode.left) {
                            replaceNode.left=null;

                        }else {
                            replaceNode.left=delNode.left;
                        }
                        replaceNode.right=delNode.right;
                    }                
                }

            }
        }

        
    }    

    
    
    public void deleteNode(T t) {
        if(t!=null) {
            root=deleteNode(root,t);
        }
    }
    //删除节点
    public Node deleteNode(Node node,T t) {
        
        if(t.compareTo(node.t)<0) {
            node.left=deleteNode(node.left,t);
        }else if(t.compareTo(node.t)>0) {
            node.right=deleteNode(node.right,t);
        }else {
            if(node.left==null&&node.right==null) {
                return null;
            }
            
            if(node.left==null&&node.right!=null) {
                return node.right;
            }else if(node.left!=null&&node.right==null) {
                return node.left;
            }
            
            if(node.left!=null&&node.right!=null) {
                  Node preNode=getReplaceNode(node);
                  preNode.left=deleteNode(node.left,preNode.t);
                  preNode.right=node.right;
                  return preNode;
            }
        }
        return node;
    }
    //删除平衡操作
    public void delBalace(Node current) {
        Node parent=current.parent;
        Node gp=parent.parent;
        Node s=parent.left==current?parent.right:parent.left;//兄弟节点
        Node ln=s.left;//兄弟节点左孩子
        Node rn=s.right;//兄弟节点右孩子
        //case 1
        if(s.color==Color.Red) {
            if(current==current.parent.left) {
                /*                      p black                                 s black
                 *                                           左旋 变色
                 *              x black       s red        ---->       p   black       rn   black
                 *  
                 *                        ln black  rn black       x     ln red
                 */
                //旋转前先变色,
                s.color=Color.Black;
                ln.color=Color.Red;
                if(gp==null) {
                     root=leftRotate(parent);

                }else if(gp.left==parent) {
                    gp.left=leftRotate(parent);
                }else if(gp.right==parent){
                    gp.right=leftRotate(parent);
                }
            }else {
                /*                    p black                           s  black 
                 *                                         右旋变色      
                 *             s  red         x  black     --->                     ln  black    p   black
                 * 
                 *    ln black   rn black                                                  rn red   x
                 * 
                 */
                s.color=Color.Black;
                rn.color=Color.Red;
                if(gp==null) {
                     root=rightRotate(parent);

                }else if(gp.left==parent) {
                    gp.left=rightRotate(parent);
                }else if(gp.right==parent){
                    gp.right=rightRotate(parent);
                }
            }

            
        }else {
            if((ln==null&&rn==null&&parent.color==Color.Black)
                    ||(ln.color==Color.Black&&rn.color==Color.Black&&parent.color==Color.Black)) {
                 s.color=Color.Red;
                 current=parent;
                 delBalace(current);//递归调用
            }else if(parent.color==Color.Red&&ln==null&&rn==null){
                /*           p red                                        p black
                 * 
                 *      x black     s black      --->             x black     s red 
                 */
                s.color=Color.Red;
                parent.color=Color.Black;
                
            }else if(rn!=null&&rn.color==Color.Red) {//  rn  为red
                if(current==parent.left) {//被删节点是左孩子
                     s.color=parent.color;
                     parent.color=Color.Black;
                     rn.color=Color.Black;
                     if(gp==null) {
                         root=leftRotate(parent);
                     }else     if(gp.left==parent) {
                         gp.left=leftRotate(parent);
                     }else if(gp.right==parent) {
                         gp.right=leftRotate(parent);
                     }
                }else {//Lr
                    /*            p                                p                             rn(p 的颜色)
                     * 
                     *     s black   x black    --->    rn            x     -->        s black           p black
                     * 
                     *        rn red                s                                                       x
                     */
                     rn.color=parent.color;
                     parent.color=Color.Black;
                     parent.left=leftRotate(s);
                     if(gp==null) {
                         root=rightRotate(parent);
                     }else if(gp.left==parent) {
                         gp.left=rightRotate(parent);
                     }else if(gp.right==parent) {
                         gp.right=rightRotate(parent);
                     }
                }
                 return ;
            }else if(ln!=null&&ln.color==Color.Red) {
                    if(current==parent.left) {
                        parent.right=rightRotate(s);
                        ln.color=parent.color;
                        parent.color=Color.Black;
                        if(gp==null) {
                             root=leftRotate(parent);
                         }else if(gp.left==parent) {
                             gp.left=leftRotate(parent);
                         }else if(gp.right==parent) {
                             gp.right=leftRotate(parent);
                         }
                    }else {
                         s.color=parent.color;
                         parent.color=Color.Black;
                         ln.color=Color.Black;
                         if(gp==null) {
                             root=rightRotate(parent);
                         }else     if(gp.left==parent) {
                             gp.left=rightRotate(parent);
                         }else if(gp.right==parent) {
                             gp.right=rightRotate(parent);
                         }

                    }
            }
            
            
        }
    }

    
    
    /*
     * 前序遍历
     */
    public void preTraversal(Node current) {
        if(current!=null) {
            System.out.println(current.t+" "+current.color);
            preTraversal(current.left);
            preTraversal(current.right);
        }
    }
    
    
    
    public static void main(String[] args) {
        
        RedBlackTree<Integer> rbt=new RedBlackTree<Integer>();
        rbt.addNode(10);
        rbt.addNode(5);
        rbt.addNode(15);
        rbt.addNode(3);
        rbt.addNode(12);
        rbt.addNode(8);
        rbt.addNode(17);
        rbt.addNode(6);
        rbt.addNode(9);
        rbt.addNode(2);
        rbt.delete(5);
        rbt.preTraversal(rbt.root);
    }
    
      
    
    

}
View Code

 

 

    

posted @ 2020-07-13 10:07  StrangerIt  阅读(729)  评论(0)    收藏  举报