美文网首页
红黑树java实现

红黑树java实现

作者: fighting_coder | 来源:发表于2018-08-13 21:42 被阅读0次

红黑树定义
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未完待续

相关文章

  • 数据结构学习_02红黑树平衡操作

    参考文章 : 红黑树原理解析以及Java实现 红黑树(五)之 Java的实现 废话不多说, 直接开始分析 一、红黑...

  • 算法与数据结构系列之[红黑树-下]

    上篇介绍了红黑树的概述,这篇贴出红黑树的java实现代码。

  • Java集合源码分析之Map(四):TreeMap

    TreeMap是红黑树的java实现,对红黑树不太了解的可以查阅这篇文章Java集合源码分析之基础(六):红黑树(...

  • 红黑树

    红黑树图Java在实现TreeMap中用到了红黑树,在此记录自己的理解。 定义 红黑树是二叉搜索树的一种实现方式,...

  • 红黑树笔记

    红黑树:R-B Tree [toc]参考:红黑树(一)之 原理和算法详细介绍红黑树(五)之 Java的实现 1 简...

  • 红黑树的简单实现(java)

    最近研究红黑树,简单的实现了一个java的红黑树代码,亲测没有问题,相关实现的说明都在注释中。实现时遇到的坑:实现...

  • 红黑树java实现

    红黑树定义1.每个节点为红色或者黑色2.根节点为黑色3.叶子节点为黑色4.如果一个节点为红色,则它的子节点只能为黑...

  • 从TreeMap学习红黑树

    红黑树是一种自平衡二叉查找树,常用于键值对存储,例如Java的TreeMap中就采用红黑树实现。它可以在O(log...

  • TreeMap源代码分析

    TreeMap是在java.util包下面,也是有序的map集合,它的原理是“红黑树”实现的: 使用了红黑二叉树的...

  • STL源码解析(1)-红黑树

    STL源码解析(1)-红黑树 STL容器之红黑树实现 C++中map和set都是基于红黑树的实现, 其迭代器也是红...

网友评论

      本文标题:红黑树java实现

      本文链接:https://www.haomeiwen.com/subject/tfdpbftx.html