java红黑树

红黑树描述

红黑树是一种二叉树,树上的节点分为红色和黑色两种。经过对节点的规则约束,保证每一个节点到叶子节点的路径不会相差两倍。红黑树比较复杂,可是它在最坏的状况下,也能保持比较高的效率。java

红黑树特色

  1. 每一个节点要么是红的,要么是黑的
  2. 根节点必定是黑的
  3. 每一个叶子节点必定是黑的
  4. 若是一个节点时红的,那么他的叶节点必定是黑的
  5. 每一个节点到期子孙叶子节点的路径上所通过的黑色节点数量一致

红黑树旋转

左旋

以B和E的链接为轴,将右侧子节点E向上移动(逆时针旋转)做为父节点node

左旋图示

左旋步骤:算法

1.节点E的父节点(即A)指向节点B的父节点(即A)spa

2.若节点E的父节点A为空,则节点E将成为新的root节点;若是左旋以前A的左节点为节点B,则如今将A的左节点指向节点E;若是以前A的右节点为节点B,则如今将A的右节点指向节点Ecode

3.将节点E的左节点指向节点Bclass

4.将节点2的父节点指向节点B效率

5.将节点B的右节点指向节点2二叉树

6.将节点B的父节点指向节点Eim

代码实现以下:数据

public class TreeMap{
    
    private Node root;//根节点

    private void rotateLeft(Node node){
         Node newRoot = node.right;
         newRoot.parent = node.parent;//节点node的父节点变为节点node.right(newRoot)的父节点
         Node A = newRoot.parent;//设置newRoot的父节点为A(即原来节点node的父节点)
         if(A == null){//若是A为空,则表示原来node是根节点,则newRoot如今也应该是根节点
             root = newRoot;
         }else if(A.left == node){//若是A的左节点指向node,则如今A的左节点应该指向newRoot
             A.left = newRoot;
         }else if(A.right == node){//若是A的右节点指向node,则如今A的右节点应该指向newRoot
             A.right = newRoot;
         }
         node.parent = newRoot;//节点newRoot变为节点node的父节点
         newRoot.left.parent = node;//节点newRoot的左节点的父节点指向节点node
         node.right = newRoot.left;//节点node的右节点指向节点newRoot的左节点
         newRoot.left = node;//节点newRoot的左节点指向node
    }
}

class Node{
   Node left;
   Node right;
   Node parent;
}

​右旋

以节点E和节点B的链接为轴,将节点E向下移(顺时针旋转)变为子节点

右旋

1.节点B的父节点(即节点A)指向节点E的父节点(即节点A)

2.若发现当前B父节点A为空,则节点B将成为新的root节点;若是节点A的左节点以前为节点E,则如今A的左节点指向节点B;若是A的右节点以前为节点E,则如今A的右节点指向节点B

3.节点2的父节点指向节点E

4.节点E的左节点指向节点2

5.节点B的右节点指向节点E

6.节点E的父节点指向节点B

代码实现以下:

public class TreeMap{

   private Node root;//根节点

   private void rotateRight(Node node){
        Node oldRoot = node.parent;
        node.parent = oldRoot.parent;//节点node的父节点指向节点node.parent(oldRoot)的父节点
        Node A = node.parent;//设置node的父节点为节点A
        if(A == null){//若是原来oldRoot是根节点,那么如今node也应该是根节点
           root = node;
        }else if(A.left == oldRoot){//若是原来A的左节点是oldRoot,那么如今A的左节点应该是node
           A.left = node;
        }else if(A.right == oldRoot){//若是原来A的右节点时oldRoot,那么如今A的右节点应该是node
           A.right = node;
        }
        oldRoot.left = node.right;//节点oldRoot的左节点指向node的右节点
        node.right.parent = oldRoot;//节点node右节点的父节点指向oldRoot
        node.right = oldRoot;//节点node的右节点指向节点oldRoot
        oldRoot.parent = node;//节点oldRoot的父节点指向node
   }

}

class Node{
    Node left;
    Node right;
    Node parent;
}

红黑树操做

插入

注意事项:

1.新插入的节点,一开始是没有颜色的,可是因为红黑要求每一个节点都应该有颜色,因此在插入后要给节点涂色。颜色只有两种——黑色和红色。若是选择黑色的话,因为红黑要求任意节点往下的路径长度(黑色节点的数量)一致,会形成新插入节点的父节点(以及再往上的节点)到下面节点的路径长度不一样(不平衡),这时候就须要进行路径的调整;若是选择红色的话,因为红色节点不计入路径长度,那么无论插入哪里,路径都是不会变化的。固然红色节点在红黑数据也有限制——红色节点下面的子节点必定是黑色,因此遇到插入节点的父节点也是红色的时候,也须要进行调整。二者相比较的话,选择黑色是必定要调整的,选择红色的是有可能须要调整,因此选择红色会更加划算一些。在红黑树的调整算法中,新插入节点都会选择红色的。

2.新插入节点会经过比较算法,最终成为某个节点的叶子节点(没有子节点),因此在调整时不须要考虑新插入节点的子节点状况

插入的几种状况:

1.新插入节点的父节点为黑色

在这种状况下新插入的节点对树是没有影响的,由于没有违反红黑树的规则。

2.新插入节点的父节点为红色

在这种状况下因为新插入节点是红色的,致使违反了红黑的规则。须要对红黑树进行调整。

删除

相关文章
相关标签/搜索