红黑树特性
- 每个节点一定是黑色或红色
- 插入的节点一定是红色
- 从任意一个节点到任意一个根节点经过的黑色节点都相同
- 红色节点的子节点和父节点必是黑色节点
- 红黑树根节点一定是黑色
代码实现
package com.platform.idleplatform.a;
public class BlackRedTree {
public static void main(String[] args) {
Node node = new Node();
node.setValue(1);
node.setRed(false);
BlackRedTree blackRedTree = new BlackRedTree(node);
blackRedTree.insert(2);
blackRedTree.insert(3);
blackRedTree.insert(4);
blackRedTree.insert(5);
blackRedTree.insert(6);
blackRedTree.insert(7);
blackRedTree.insert(8);
blackRedTree.insert(9);
blackRedTree.insert(10);
blackRedTree.print(blackRedTree.findRoot(node));
}
private Node root;
public Node findRoot(Node node){
Node p = node;
while (true) {
if (p.getParent() != null) {
p = p.getParent();
}else {
return p;
}
}
}
public BlackRedTree(Node root){
this.root =root;
}
public void insert(Integer value){
Node node = new Node();
node.setRed(true);
node.setValue(value);
insert(node,value);
fix(node);
}
public void print(Node node){
if (node == null) {
return;
}
System.out.println(node.getValue() + (node.getRed() ? "红" : "黑"));
System.out.println(node.getValue().toString() + '左');
print(node.getLeft());
System.out.println(node.getValue().toString() + '右');
print(node.getRight());
}
private void insert(Node node,Integer value){
Node p = findRoot(this.root);
while (true){
if (node.getValue() > p.getValue()){
if (p.getRight() != null){
p = p.getRight();
}else {
p.setRight(node);
node.setParent(p);
break;
}
}else {
if (p.getLeft() != null){
p = p.getLeft();
}else {
p.setLeft(node);
node.setParent(p);
break;
}
}
}
}
//进行左旋
private void leftRota(Node node){
Node parent = node.getParent();
Node right = node.getRight();
if (right.getLeft() != null) {
node.setRight(right.getLeft());
}
if (parent != null){
parent.setRight(right);
}
right.setParent(node.getParent());
node.setParent(node.getRight());
node.setRight(right.getLeft());
right.setLeft(node);
}
//进行右旋
private void righttRota(Node node){
Node parent = node.getParent();
Node left = node.getLeft();
if (left.getLeft() != null) {
node.setRight(left.getLeft());
}
if (parent != null) {
parent.setLeft(left);
}
left.setParent(node.getParent());
node.setParent(node.getLeft());
node.setLeft(left.getRight());
left.setRight(node);
}
//进行修复
private void fix(Node node) {
Node parent = node.getParent();
if (parent != null) {
//父节点为为黑色节点不用修复
if (!parent.getRed()) {
return;
}
Node graparent = parent.getParent();
//父节点左节点
if (parent.getLeft() == node) {
//为爷爷节点左节点
if (graparent.getLeft() == parent) {
//左左双红
if (!graparent.getRight().getRed() || graparent.getRight() == null) {
//叔叔节点为黑或为空 为父节点左节点 爷爷节点左节点 把父节点变为黑色 把爷爷节点变为红色,然后对爷爷节点右旋 对应情景4.2.1
parent.setRed(false);
graparent.setRed(true);
righttRota(graparent);
} else {
//叔叔节点为红色,把叔叔节点变为黑色 父节点变为黑色 把爷爷节点变为红色,以爷爷节点为当前节点,进行下一轮修复 对应情景4.1
graparent.getRight().setRed(false);
parent.setRed(false);
graparent.setRed(true);
fix(graparent);
}
} else {
//为爷爷节点右节点 父节点的左节点 且叔叔节点为空或黑色 先对父节点右旋 然后以父节点为当前节点进行下一轮跳转 对应情景4.3.2
if (graparent.getLeft() == null || !graparent.getLeft().getRed()) {
righttRota(parent);
fix(parent);
} else {
//叔叔节点为红色,把叔叔节点变为黑色 父节点变为黑色 把爷爷节点变为红色,以爷爷节点为当前节点,进行下一轮修复 对应情景4.1
graparent.getLeft().setRed(false);
parent.setRed(false);
graparent.setRed(true);
fix(graparent);
}
}
} else {
//叔叔节点为黑或为空 为父节点右节点 爷爷节点左节点 先对父节点进行左旋,然后以父节点为当前节点继续调整 对应情景4.2.2
if (graparent.getLeft() == parent) {
if (!graparent.getLeft().getRed() || graparent.getLeft() == null) {
leftRota(parent);
fix(parent);
} else {
//叔叔节点为红色,把叔叔节点变为黑色 父节点变为黑色 把爷爷节点变为红色,以爷爷节点为当前节点,进行下一轮修复 对应情景4.1
graparent.getRight().setRed(false);
parent.setRed(false);
graparent.setRed(true);
fix(graparent);
}
} else {
//叔叔节点为黑或为空 为父节点右节点 爷爷节点右节点 把父节点变为黑色 把爷爷节点变为红色,然后对爷爷节点左旋 对应情景4.3.1
if (graparent.getLeft() == null || !graparent.getLeft().getRed()) {
parent.setRed(false);
graparent.setRed(true);
leftRota(graparent);
} else {
//叔叔节点为红色,把叔叔节点变为黑色 父节点变为黑色 把爷爷节点变为红色,以爷爷节点为当前节点,进行下一轮修复 对应情景4.1
graparent.getLeft().setRed(false);
parent.setRed(false);
graparent.setRed(true);
fix(graparent);
}
}
}
}
findRoot(node).setRed(false);
}
}
//红黑树节点
class Node{
//是否为红色节点 0为红色节点 1为黑色节点
private Boolean isRed;
//存放左节点
private Node left;
//存放右节点
private Node right;
//存放值
private Integer value;
//存放父节点
private Node parent;
public Boolean getRed() {
return isRed;
}
public void setRed(Boolean red) {
isRed = red;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
}