package第一章数据结构实现;public classRBTree {
TreeNode head;//树的头节点//创建红色的默认节点,但是未设置父节点
public TreeNode getNode(intval) {
TreeNode defaultNode= newTreeNode(val);
defaultNode.color= Color.RED; //默认为红色
returndefaultNode;
}//打印树
public voidprintTree(TreeNode node) {if(head==null) {
System.out.println("树是空的,请确认init()方法已经执行!");return;
}if(node==null) return;else{//前序遍历
System.out.print("节点的值:"+node.val+" 节点的颜色:"+node.color);if(node.parent!=null) System.out.println(" 节点的父节点:"+node.parent.val);else System.out.println(" 这是根节点");
printTree(node.left);
printTree(node.right);
}
}//===================================================================================================//树的初始化
public void init(int[] arr) {for(int i=0;i
insert(head,null,arr[i],-1);
}
}//inset 开始插入 ,lr为0代表left lr为1代表right lr为-1表示是根节点
public void insert(TreeNode head,TreeNode parent,int i,intlr) {
if(head==null) {
TreeNode x=getNode(i);
x.parent=parent;
head= x;
if(lr==1) parent.right =head;else if(lr==0) parent.left =head;
insert1(head);
}else { //递归插入
if(i>head.val) insert(head.right,head,i,1);if(i
}
}//case1:插入的节点为根节点,将插入节点置为红色,前期x的父节点x.parent必须确定下来
public voidinsert1(TreeNode x) {if(x.parent==null) {
x.color=Color.BLACK;
head= x; //将首节点指向x
return;
}elseinsert2(x);
}//case2:插入的节点不为根节点//且插入的节点的父节点为黑色的,那么红黑树是不用调节的
public voidinsert2(TreeNode x) {if(x.parent.color==Color.BLACK) return;elseinsert3(x);
}//case3如果插入节点的父节点为红色 ,违反父子节点都为红色的//如果叔叔节点为红色,只需将叔叔节点和父节点同时设为黑色,同时祖父节点设为红色//但这会引入新问题,祖父节点和其自身父节点有可能都为红色,使用尾递归向上上滤
public voidinsert3(TreeNode x) {
TreeNode par= x.parent; //父节点
TreeNode gra = par.parent; //祖父节点
TreeNode unc = (par==gra.left)? gra.right : gra.left; //叔叔节点
if(unc!=null && unc.color==Color.RED) {
unc.color=Color.BLACK;
par.color=Color.BLACK;
gra.color=Color.RED;
insert1(gra);//尾递归上滤
} elseinsert4(x);
}//case4: 如果叔叔节点为黑色或者null
public voidinsert4(TreeNode x) {
TreeNode par= x.parent; //父节点
TreeNode gra = par.parent; //祖父节点//如果父节点是祖父节点的左节点,但x是父节点的右节点,交换x和其父节点,且x变为其原父节点的父节点
if(par==gra.left && x==par.right) {
gra.left=x;
x.left=par;
x.parent=gra;
par.right= null;
par.parent=x;
insert5(par);
}//如果父节点是祖父节点的右节点,但是x是父节点的左节点,交换x和其父节点,且x变为祖父节点的右节点
else if(par==gra.right && x==par.left) {
gra.right=x;
x.right=par;
x.parent=gra;
par.left= null;
par.parent=x;
insert5(par);
}else{
insert5(x);//因为这个x节点有可能变为父节点了,所以要在insert5进行判断是否为变换后的父节点
}
}public voidinsert5(TreeNode x) {
TreeNode par= x.parent; //父节点
TreeNode gra = par.parent; //祖父节点
TreeNode ggra = gra.parent; //祖父节点的父节点
if(x==par.left) {
gra.left=par.right;
par.right=gra;
par.parent=ggra;
gra.parent=par;if(gra.left!=null) gra.left.parent = gra; //如果节点不为空更新父节点信息//ggra.left = par;
if(ggra==null) head =par;else{if(par.val>ggra.val) ggra.right =par;else ggra.left =par;
}
}else if(x==par.right) {//if(x.val==12) System.out.println("12的父节点的左节点:"+par.left.val);
gra.right =par.left;
par.left=gra;
par.parent=ggra;
gra.parent=par;if(gra.right!=null) gra.right.parent = gra; //要更新父节点信息
if(ggra==null) head = par; //根节点要重新指向
else{if(par.val>ggra.val) ggra.right =par;else ggra.left =par;
}
}//颜色变化
gra.color =Color.RED;
par.color=Color.BLACK;
}//=======================================================================================================
public static voidmain(String[] args) {int[] arr = {5,3,1,7,9,6,15,12,14,13};
RBTree rbt= newRBTree();
rbt.init(arr);
rbt.printTree(rbt.head);
}//红黑树节点
private classTreeNode{
Color color=Color.RED;intval;
TreeNode left;
TreeNode right;
TreeNode parent;TreeNode(intvalue) {
val=value;
}
}//树节点枚举类
private enumColor{
RED,BLACK;
}
}