红黑树的五个性质:
1)每个结点要么是红的,要么是黑的。
2)根结点是黑的。
3)每个叶结点,即空结点(NIL)是黑的。
4)如果一个结点是红的,那么它的俩个儿子都是黑的。
5)对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点。
红黑树插入的几种情况:
1、树是空的,直接将节点设置为根节点,颜色为黑;
public void case1(RBnode T,RBnode newNode){
if(newNode.getParent()==null){
newNode.setColor(0);
T = newNode;
}else{
case2(T,newNode);
}
}
2、父节点是黑的,直接插在父节点下面
public RBnode case2(RBnode T,RBnode newNode){
if(newNode.getParent().getColor()==0){
return T;
}else{
return case3(T,newNode);
}
}
3、叔叔节点存在且节点的叔叔节点是红的
将父节点和叔叔节点设置为黑色的,祖父节点设置为红色的,将当前节点设置为祖父节点,因为祖父节点是红色的,1、可能违反根节点是黑色的要求 ;2、由于祖父节点为红色,而祖父的父亲节点可能也是红色;综合1、2从case1开始,以祖父节点为当前节点进行递归。
public RBnode case3(RBnode T,RBnode newNode){
RBnode y = newNode.getParent().getParent().getRight();//叔父节点
if(y!=null&&y.getColor()==1){
newNode.getParent().setColor(0);//当前节点父节点和叔父节点涂黑,祖父节点涂红
y.setColor(0);
newNode.getParent().getParent().setColor(1);
case1(T,newNode);
return T;
}else{
return case4(T,newNode.getParent().getParent());
}
}
4、叔叔节点为空或者叔叔节点是黑色,父亲节点是红色的情况
在这里又可以分为两种情况
(1)、当前节点为父节点的右子树,父亲节点为祖父节点的左子树
(2)、当前节点为父节点的左子树,父亲节点为祖父节点的右子树
上图是第一种情况
//情形4: 父节点P是红色,叔叔节点U是黑色或NIL; 插入节点N是其父节点P的右孩子,而父节点P又是其父节点的左孩子。(旋转父节点)
public RBnode case4(RBnode T,RBnode newNode){
if(newNode == newNode.getParent().getRight()&&newNode.getParent()==newNode.getParent().getParent().getLeft()){
leftRotate(T,newNode.getParent().getParent());
newNode = newNode.getLeft();
}else if(newNode == newNode.getParent().getLeft()&&newNode.getParent()==newNode.getParent().getParent().getRight()){
rightRotate(T,newNode.getParent().getParent());
newNode = newNode.getRight();
}
return case5(T,newNode);
}
继续经过情况5进行进一步的处理
5、父节点P是红色,叔叔节点U是黑色或NIL;(旋转祖父节点)
在这里又可以分为两种情况
(1)、当前节点为父节点的左子树,父亲节点为祖父节点的左子树
(2)、当前节点为父节点的右子树,父亲节点为祖父节点的右子树
public RBnode case5(RBnode T,RBnode newNode){
newNode.getParent().setColor(0);
newNode.getParent().getParent().setColor(1);
if(newNode == newNode.getParent().getLeft()&&newNode.getParent()==newNode.getParent().getParent().getLeft()){
rightRotate(T,newNode.getParent().getParent());
}else{
/* 反情况,N 是其父节点的右孩子,而父节点P又是其父G的右孩子 */
leftRotate(T,newNode.getParent().getParent());
}
return T;
}
删除操作:http://blog.csdn.net/chenhuajie123/article/details/11951777
红黑树可以保持O(logn)的速度进行查找和删除