建议配合算法导论伪代码一起阅读,便于理解。
package test;
public class BTtree {
//左旋,右孩子不能为空,因为右孩子要成为cur的父节点
public void leftRotate(Root T, Node cur){
Node right = cur.right;
cur.right = right.left;
if(right.left!=T.nil)
right.left.parent=cur;
Node parent = cur.parent;
if(parent==null){
T.root=cur;
}else if(parent.left==cur){
parent.left=right;
}else{
parent.right = right;
}
right.parent = parent;
cur.parent=right;
right.left=cur;
}
//右旋,左孩子不能为空
public void rightRotate(Root T, Node cur){
Node left = cur.left;
cur.left = left.right;
if(left.right!=T.nil)
left.right.parent=cur;
Node parent = cur.parent;
if(parent==null){
T.root = left;
}else if(parent.left==cur){
parent.left=left;
}else{
parent.right = left;
}
left.parent = parent;
cur.parent=left;
left.right=cur;
}
public void RB_insert(Root T,Node z){
Node y = null;
Node x = T.root;
while (x!=null){
y=x;
if(z.val<x.val){
x=x.left;
}else{
x=x.right;
}
}
z.parent = y;
//判断是否根节点为空
if(T.root==null){
T.root = z;
}else if(z.val<y.val){
y.left=z;
}else {
y.right=z;
}
z.left=T.nil;
z.right=T.nil;
z.color=1;
RB_insert_fixup(T,z);
}
//旋转时可以推断出左右孩子满足相应的不为空的条件
public void RB_insert_fixup(Root T,Node z){
Node cur = z;
while (cur.parent!=null&&cur.parent.color==1){
if(cur.parent==cur.parent.parent.left){
//由于cur.parent为红故cur.parent.parent必定不是null所以不需要判断。
//cur.parent是未经过改变颜色前已经是红色,可以证明其父节点必定存在
//并且叔叔节点一定不为null,如果叔叔为null,红黑树不平衡
//叔叔节点为红色
Node uncle = cur.parent.parent.right;
if(uncle.color==1) {
cur.parent.color=0;
uncle.color=0;
cur.parent.parent.color=1;
cur=cur.parent.parent;
}else {//叔叔节点为黑色,且下面未对叔叔节点进行调整
if(cur==cur.parent.right){
cur=cur.parent;
leftRotate(T,cur);
}
cur.parent.color=0;
cur.parent.parent.color=1;
rightRotate(T,cur.parent.parent);
}
}else{
Node uncle = cur.parent.parent.left;
//叔叔节点为红色
if(uncle.color==1) {
cur.parent.color=0;
uncle.color=0;
uncle.parent.color=1;
cur=cur.parent.parent;
}else{//叔叔节点为null
if(cur==cur.parent.left){
cur=cur.parent;
rightRotate(T,cur);
}
cur.parent.color=0;
cur.parent.parent.color=1;
leftRotate(T,cur.parent.parent);
}
}
}
T.root.color=0;
}
public void RB_TRANSPLANT(Root T,Node u,Node v){
if(u.parent==null){
T.root=v;
}else if(u.parent.left==u){
u.parent.left=v;
}else{
u.parent.right=v;
}//由于T.nil的存在v不可能为null
v.parent=u.parent;
}
public Node RB_DELETE(Root T,Node z){
/* ① 被删除节点没有儿子,即为叶节点。那么,直接将该节点删除就OK了。
② 被删除节点只有一个儿子。那么,直接删除该节点,并用该节点的唯一子节点顶替它的位置。
③ 被删除节点有两个儿子。那么,先找出它的后继节点;然后把“它的后继节点的内容”复制给“该节点的内容”;
之后,删除“它的后继节点”。在这里,后继节点相当于替身,在将后继节点的内容复制给"被删除节点"之后,再将后继节点删除。
这样就巧妙的将问题转换为"删除后继节点"的情况了,下面就考虑后继节点。 在"被删除节点"有两个非空子节点的情况下,
它的后继节点不可能是双子非空。既然"的后继节点"不可能双子都非空,就意味着"该节点的后继节点"要么没有儿子,
要么只有一个儿子。若没有儿子,则按"情况① "进行处理;若只有一个儿子,则按"情况② "进行处理。
*/
Node y = null;
Node x = null;
//若左右孩子有一个为空,把z赋给y. 则直接删除当前节点
if(z.left==T.nil||z.right==T.nil){
y=z;
//否则把中序遍历z的后继节点赋值给y
}else{
y=TREE_SUCCESSOR(T,z);
}
//y的左孩子不是空
if(y.left != T.nil){
x = y.left;
}else {
x=y.right;
}
x.parent = y.parent;
if(y.parent==T.nil){
T.root=x;
}else if(y==y.parent.left){
y.parent.left=x;
}else{
y.parent.right=x;
}
if(y!=z){
z.val=y.val;
}
if(y.color==0){
RB_DELETE_FIXUP(T,x);
}
return y;
}
public Node TREE_SUCCESSOR(Root T,Node z){
if(z.right!=T.nil){
return TREE_MINNUM(T,z.right);
}
Node y =z.parent;
while (y!=T.nil&&z==y.right){
z=y;
y=y.parent;
}
return y;
}
public Node TREE_MINNUM(Root T,Node x){
while (x.left!=T.nil){
x=x.left;
}
return x;
}
public void RB_DELETE_FIXUP(Root T,Node x){
//如果没有T.nil后补的节点可能为null则会出错
while (x!=T.root&&x.color==0){
if(x==x.parent.left){
Node brother = x.parent.right;//broter必定不是空
//case1兄弟节点为红色。经过case1后兄弟节点必定为黑色。因为兄弟节点变为了原红色节点的子节点。
if(brother.color==1){
x.parent.color=1;
brother.color=0;
leftRotate(T,x.parent);
brother = x.parent.right;
}
//case2兄弟子节点都为黑色,由性质推断出brother两个孩子都不为空。
//若x.p为红色,则结束,因为兄弟节点黑高减一,否则x.p表示两重黑色,
if(brother.left.color==0&&brother.right.color==0){
brother.color=1;
x=x.parent;
}//有一个孩子不为黑色
else{
//case3左孩子为红色,右孩子为黑色,转化为情况四
if(brother.right.color==0){
brother.color=1;
brother.left.color=0;
rightRotate(T,brother);
brother=x.parent.right;
}
brother.color=x.parent.color;//如果直接令brother.color=1;会出现黑高与其他分支不等
x.parent.color=0;
brother.right.color=0;
leftRotate(T,x.parent);
x=T.root;
}
}else {
Node brother = x.parent.left;
if(brother.color==1){
x.parent.color=1;
brother.color=0;
rightRotate(T,x.parent);
brother=x.parent.left;
}
if(brother.left.color==0&&brother.right.color==0){
brother.color=1;
x=x.parent;
}
else{
if(brother.left.color==0){
brother.color=1;
brother.right.color=0;
leftRotate(T,brother);
brother=x.parent.left;
}
brother.color=x.parent.color;
x.parent.color=0;
brother.left.color=0;
rightRotate(T,x.parent);
x=T.root;
}
}
}
x.color=0;
}
}
class Root{
public Node root;
public Node nil=new Node();
public Root(){
nil.color=0;
}
}
class Node {
public int val;
public Node parent=null;
public int color;//1为红色0为黑色
public Node left=null;
public Node right=null;
public Node(int val) {
this.val = val;
}
public Node(){}
}