红黑树java实现

红黑树定义
1.每个节点为红色或者黑色
2.根节点为黑色
3.叶子节点为黑色
4.如果一个节点为红色,则它的子节点只能为黑色
5.从一个节点到叶子节点的所有路径上黑色节点个数相同

红黑树的java数据结构

public class RBTree<T extends Comparable<T>>{
        private RBTNode mRoot;
        private static final boolean RED=false;
        private static final boolean BLACK=true;
        public class RBTNode<T extends Comparable<T>>{
                  boolean color;
                  T key;
                  RBTNode<T> left;
                  RBTNode<T> right;
                  RBTNode<T> paraent;
                  public RBTNode(T key,boolean color, RBTNode<T> parent,RBTNode<T> left,  RBTNode<T> right){
                 this.key=key;
                 this.color=color;
                 this.parent=parent;
                 this.left=left;
                 this.right=right;
              }
       }
}

红黑树插入过程中会有左旋和右旋,下面介绍这两种情况
1.左旋
//todo 插入图片

//java 代码
private void leftRotate(RBTNode<T> x){
           //设置x的右孩子为y
           RBTNode<T> y=x.right;
          //将y的左孩子设置为x的右孩子
           x.right=y.left;
          if(y.left != null){
             y.left.parent=x; 
          }
         y.parent=x.parent;
         if(x.parent == null){
           this.mRoot=y;
         }else{
              if(x.parent.left==x){
                   x.parent.left=y;
              }
                  x.parent.right=y;
             }
         y.left=x;
         x.parent=y;
}
  1. 右旋
    //todo 插入图片
//java代码
private void rightRotate(RBTNode<T> x){
         //设置x的左孩子为y
         RBTNode<T> y=x.left;
         //将x的右孩子设置为y的左孩子
         y.left=x.right;
         if(x.right != null){
           x.right.parent=y;
         }
         //将y的parent设置为x的parent
         x.parent=y.parent;
         if(y.parent == null){
           this.mRoot=x;
        }else{
            if(y.parent.left == y){
                 y.parent.left=x;
             }else{
                y.parent.right=x;
               } 
       }
        x.right=y;
        y.parent=x;
}

红黑树的添加
红黑树添加节点默认为红色,添加后分三种情况
1.父节点为红色,叔叔节点为红色
将父节点和叔叔节点调整为黑色,祖父节点调整为红色,将祖父节点作为新的节点重新调整
2.父亲节点为红色,叔叔节点为黑色,自己为父亲节点的左孩子
将父节点调整为黑色,祖父节点调整为红色,对祖父节点进行右旋操作
3.父节点为红色,叔叔节点为黑色,自己为父亲节点的右孩子
对父亲节点左旋操作,则转化成情况2

//java代码
private void insert(RBTNode<T> node){
           int cmp;
           RBTNode<T> y=null;
           RBTNode<T>  x=this.mRoot;
           //查找要插入的节点
           while(x != null){
               y=x;
               cmp=node.key.compareTo(x.key)
               if (cmp<0){
                     x=x.left;
               } else{
                    x=x.right;
               }
          }
          node.parent=y;
          if( y != null){
                cmp=node.key.compareTo(y.key);
                if(cmp<0){
                    y.left=node;
                }else{
                   y.right=node;
                  }
         }else{
             this.mRoot=node;
           }
          //将节点置为红色
          node.color=RED;
          //调整红黑树
          insertFixUp(node);
}

添加节点后台调整红黑树 java代码

private void insertFixUp(RBTNode<T> node){
           RBTNode<T> parent, gparent;
           while((parent=parentOf(node))!=null&&isRed(parent)){
                gparent=parentOf(parent);
               //父节点是祖父节点的左孩子
               if(parent==gparent.left){
                     RBTNode<T> uncle=gparent.right;
                      //case1: 叔叔节点为红色
                     if(uncle!=null && uncle.color==RED){
                             setBlack(parent);
                             setBlack(parent);
                             setRed(gparent);
                             node=parent;
                             continue;
                       }
                     //case2: 叔叔节点为黑色,且自己为右节点
                     if(node==parent.right){
                          RBTNode<T> tmp;
                           leftRotate(parent);
                           tmp=parent;
                           parent=node;
                           node=parent;
                    }
                   //case3: 叔叔节点为黑色,且自己为左节点
                   setBlack(parent);
                   setRed(gparent);
                   rightRotate(gparent);
                }else{ //父节点是祖父节点的右孩子
                   RBTNode<T> uncle=gparent.right;
                   //case1: 叔叔节点为红色
                    if(uncle!=null && uncle.color==RED){
                             setBlack(parent);
                             setBlack(parent);
                             setRed(gparent);
                             node=parent;
                             continue;
                     }
                   //case2: 叔叔节点为黑色,且自己为左节点
                   if(node==parent.left){
                         RBTNode<T> tmp;
                         rightRotate(parent);
                         tmp=parent;
                         parent=node;
                         node=tmp;
                    }
                    setBlack(parent);
                    setRed(gparent);
                    leftRotate(gparent);
                }
          }
      //将根节点设置为黑色
      setBlack(this.mRoot);
}

红黑树删除
红黑树的删除分为4种情况
1.兄弟节点为红色,且父亲节点为黑色,将父亲节点设置为红色,兄弟节点设置为黑色,对父亲节点旋转操作
2.兄弟节点为黑色,且兄弟节点的子节点都为黑色,将兄弟节点调整为红色
3.兄弟节点为黑色,且兄弟节点的左孩子为红色,右孩子为黑色,将父节点设置为黑色,兄弟节点右孩子设置为黑色,对父节点选择操作
4.兄弟节点为黑色,且兄弟节点的左孩子为黑色,右孩子为红色,将兄弟节点设置为红色,右孩子设置为黑色,对兄弟节点进行旋转操作。

private void remove(RBTNode<T> node){
         RBTNode<T> child,parent;
         boolean color;
         if((node.left!=null)&&(node.right!=null)){
                  RBTNode<T> replace=node;
                  replace=repalce.right;
                 while(replace.left!=null)
                         replace=replace.left;
                 if(parent(node)!=null){
                         if(parent(node).left=node)
                                  parentOf(node).left=node;
                         else
                                  parentOf(node).right=node;
                 }else{
                       this.mRoot=node;
                 }
                 child=replace.right;
                 parent=parentOf(replace);
                 color=colorOf(replace);
                 if(parent==node)
                         parent=replace;
                 else{
                        if(child!=null){
                                setParent(child,parent);
                        }
                        parent.left=child;
                        replace.right=node.right;
                       setParent(node.right,replace);
                }
                 replace.parent=node.parent;
                 replace.color=node.color;
                 replace.left=node.left;
                 node.left.parent=replace;
                 if(color==BLACK)
                         removeFixUp(child,parent);
                 node=null;
                 return;
         }
}

删除节点后调整代码

private void removeFixUp(RBTNode<T> child,RBTNode<T> parent){
           RBTNode<T> other;
          while((node==null || isBlack(node))&&(node!=this.mRoot)){
                if(parent.left==node){
                         other=parent.right;
                          if(isRed(other)){
                          //case1: 兄弟节点是红色
                           setBlack(other);
                           setRed(parent);
                           leftRotate(parent);
                           other=parent.right;
                           }
                          if((other.left!=null&&Color(other.left)==BLACK)&&(other.right==null&&Color(other.right)==BLACK)){
                          //case2
                          setRed(other);
                          node=parent;
                          parent=parentOf(node);
                          }else{
                          //case3
                          if(other.right!=null&&Color(other.right)==RED){
                              setColor(other,ColorOf(parent));
                              setBlack(parent);
                              setBlack(other.right);
                              leftRotate(parent)
                              node=this.mRoot;
                           }
                           setBlack(other.left);
                           setRed(other);
                           rightRotate(other);
                           other=parent.right;
                           break;
                    }
             }
          else{
                  other=parent.left;
                  if(isRed(other)){
                          //case1: 兄弟节点是红色
                           setBlack(other);
                           setRed(parent);
                           rightRotate(parent);
                           other=parent.left;
                  }
              if((other.left!=null&&Color(other.left)==BLACK)&& 
                (other.right==null&&Color(other.right)==BLACK)){
                          //case2
                          setRed(other);
                          node=parent;
                          parent=parentOf(node);
                          }else{
                           if(other.left!=null&&Color(other.left)==RED){
                              setColor(other,ColorOf(parent));
                              setBlack(parent);
                              setBlack(other.right);
                              rightRotate(parent)
                              node=this.mRoot;
                          }
                           setBlack(other.left);
                           setRed(other);
                           leftRotate(other);
                           other=parent.right;
                           break;
                  }
            }
if (node!=null)
        setBlack(node);
}

//todo未完待续

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容