1.红黑树首先是一颗二叉搜索树
2.每一个节点要么为红色,要么为黑色
3.根节点为黑色
4.每条路径的黑色节点数相同
5.每条路径中不能有两个连续的红色节点node
每次插入的节点初始化为红色
插入情形总共分为如下几种状况
1.插入节点父节点为黑色
在这种状况中,由于插入节点为红色,因此不会影响此红黑树的结构,直接插入便可
2.插入节点父节点为红色
在此种状况中插入会破坏红黑树的平衡,必须进行自平衡操做,主要是旋转操做,首先咱们对一些概念就行解释bash
2.1插入节点的叔叔节点为红色
ide
2.2.1插入节点的父节点为祖父节点的左子节点
性能
2.2.1.1插入节点为父节点的左子节点
ui
public class RBNode {
RBNode left;
RBNode right;
RBNode parent;
String color;
int val;
public RBNode(int val) {
this.val=val;
this.color="R";
}
//插入节点
public void insert(RBNode node) {
if(node.val<this.val) {
if(this.left==null) {
this.left=node;
node.parent=this;
//插入以后调用自平衡方法进行平衡
fixed3(node);
}else {
this.left.insert(node);
}
}
if(node.val>this.val) {
if(this.right==null) {
this.right=node;
node.parent=this;
//插入以后调用自平衡方法进行平衡
fixed3(node);
}else {
this.right.insert(node);
}
}
}
public void fixed3(RBNode node) {
if(node==null) return;
//若是节点为根节点则变为黑色;
if(node.parent==null) {
node.color="B";
return;
}
//若是父节点为黑色则不处理,父节点为红色则必须进行处理才能保持平衡,父节点为红色时,祖父节点必然存在,由于不能有两个连续的红色节点
if(node.parent.color=="R") {
//1.父节点和叔节点都为红色
if(node.parent.parent.left!=null&&node.parent.parent.right!=null&&node.parent.parent.left.color=="R"&&node.parent.parent.right.color=="R") {
node.parent.parent.left.color="B";
node.parent.parent.right.color="B";
node.parent.parent.color="R";
fixed3(node.parent.parent);
return;
}
//2.叔叔节点为黑色或不存在
//2.1 插入节点的父节点为祖父节点的左节点
if(node.parent.equals(node.parent.parent.left)&&(node.parent.parent.right==null||node.parent.parent.right.color=="B")) {
//2.1.1 插入节点为父节点的左节点
if(node.equals(node.parent.left)) {
node.parent.color="B";
node.parent.parent.color="R";
node.parent.parent.rightRotate();
return;
}
//2.1.2 插入节点为父节点的右节点
if(node.equals(node.parent.right)) {
node = node.parent;
node.leftRotate();
fixed3(node.left);
return;
}
}
//2.2 插入节点的父节点为祖父节点的右节点
if(node.parent.equals(node.parent.parent.right)&&(node.parent.parent.left==null||node.parent.parent.left.color=="B")) {
//2.2.1 插入节点为父节点的左节点
if(node.equals(node.parent.left)) {
node = node.parent;
node.rightRotate();
fixed3(node.right);
return;
}
//2.2.2 插入节点为父节点的右节点
if(node.equals(node.parent.right)) {
node.parent.color="B";
node.parent.parent.color="R";
node.parent.parent.leftRotate();
return;
}
}
}
}
//左旋转操做
public void leftRotate() {
RBNode newNode = new RBNode(this.val);
newNode.left=this.left;
newNode.right=this.right.left;
if(newNode.left!=null) {
newNode.left.parent=newNode;
}
if(newNode.right!=null) {
newNode.right.parent=newNode;
}
newNode.color=this.color;
this.val=this.right.val;
this.color=this.right.color;
this.left=newNode;
this.right=this.right.right;
if(this.left!=null) {
this.left.parent=this;
}
if(this.right!=null) {
this.right.parent=this;
}
}
//右旋转操做
public void rightRotate() {
RBNode newNode = new RBNode(val);
newNode.color=this.color;
newNode.right=this.right;
newNode.left=this.left.right;
if(newNode.left!=null) {
newNode.left.parent=newNode;
}
if(newNode.right!=null) {
newNode.right.parent=newNode;
}
this.val=this.left.val;
this.color=this.left.color;
this.left=this.left.left;
this.right=newNode;
if(this.left!=null) {
this.left.parent=this;
}
if(this.right!=null) {
this.right.parent=this;
}
}
//前序遍历
public void frontShow() {
System.out.println(this.color+" "+this.val);
if(this.left!=null) {
this.left.frontShow();
}
if(this.right!=null) {
this.right.frontShow();
}
}
//重写equals判断节点是否相等
@Override
public boolean equals(Object obj) {
if((RBNode)obj==null) {
return false;
}
if(this.val==((RBNode)obj).val) {
return true;
}
return false;
}
}
复制代码
为何有了AVL树还要红黑树?
红黑树不追求"彻底平衡",即不像AVL要求节点的高度差<=1,它只要求部分达到平衡,可是提出了为节点增长颜色,红黑是用非严格的平衡来换取增删节点时候旋转次数的下降,而AVL是严格平衡树,所以在增长或者删除节点的时候,根据不一样状况,旋转的次数比红黑树要多。
可是红黑树的搜索性能要逊于AVL,由于AVL是彻底平衡的,红黑树要比AVL最多多一层。
this
最后删除操做我还没学会。spa