RBTree
- 根节点是黑色
- 每个叶子节点都是黑色的空结点(NIL结点)(为了简单期间,一般会省略该节点)
- 如果一个节点是红色的,则它的子节点必须是黑色的(父子不能同为红)
- 从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点(平衡的关键)
- 新插入节点默认为红色,插入后需要校验红黑树是否符合规则,不符合则需要进行平衡
节点
package com.richard.brtree;
public class BRTreeNode {
private int key;
private boolean isBlack;
private BRTreeNode left;
private BRTreeNode right;
private BRTreeNode parent;
public BRTreeNode(int key) {
this.key = key;
this.isBlack = false; // 新节点默认是红
}
@Override
public String toString() {
return "BRTreeNode{" +
"key=" + key +
", color=" + (isBlack==true?"BLACK":"RED")+
'}';
}
public int getKey() {
return key;
}
public void setKey(int key) {
this.key = key;
}
public boolean isBlack() {
return isBlack;
}
public void setBlack(boolean black) {
isBlack = black;
}
public BRTreeNode getLeft() {
return left;
}
public void setLeft(BRTreeNode left) {
this.left = left;
}
public BRTreeNode getRight() {
return right;
}
public void setRight(BRTreeNode right) {
this.right = right;
}
public BRTreeNode getParent() {
return parent;
}
public void setParent(BRTreeNode parent) {
this.parent = parent;
}
}
实现
package com.richard.brtree;
import com.sun.media.sound.FFT;
import com.sun.xml.internal.bind.v2.model.core.ID;
/**
* 红黑树
*/
public class RBTree {
// 根节点
BRTreeNode root;
/**
* 遍历节点
* @param node
*/
public void list(BRTreeNode node) {
if (node == null) {
return ;
}
// 到叶子了 递归终止条件
if (node.getLeft() == null && node.getRight() == null) {
System.out.println(node);
return ;
}
// 遍历节点
System.out.println(node);
list(node.getLeft());
list(node.getRight());
}
/**
* 插入节点
* @param key
*/
public void insert(int key) {
BRTreeNode node = new BRTreeNode(key);
// 插入根节点
if (root == null) {
node.setBlack(true); // 根是黑的
root = node;
return ;
}
BRTreeNode parent = root;
BRTreeNode son = null;
// 左孩子
if (key <= parent.getKey()) {
son = parent.getLeft();
} else { // 右孩子
son = parent.getRight();
}
// 递归查找
while (son != null) {
parent = son;
if (key <= parent.getKey()) {
son = parent.getLeft();
} else {
son = parent.getRight();
}
}
// 开始添加
if (key <= parent.getKey()) {
// 添加左孩子
parent.setLeft(node);
} else {
// 添加右孩子
parent.setRight(node);
}
node.setParent(parent);
balanceInsert(node);
}
/**
* 插入自平衡
* 左旋右旋颜色反转
* @param node
*/
private void balanceInsert(BRTreeNode node) {
BRTreeNode father, gFather;
// 父节点是红的
while ((father=node.getParent()) != null && father.isBlack() == false) {
gFather = father.getParent();
// 父节点在祖父节点的左面
if (gFather.getLeft() == father) {
BRTreeNode uncle = gFather.getRight();
if (uncle != null && uncle.isBlack() == false) {
// 颜色反转
setBlack(father);
setBlack(uncle);
setRed(gFather);
node = gFather;
continue;
}
if (node == father.getRight()) {
// 进行左旋
leftRotate(father);
// 交换
BRTreeNode tmp = node;
node = father;
father = tmp;
}
setBlack(father);
setRed(gFather);
// 右旋
rightRotate(gFather);
} else {// 父节点在祖父节点的右面
BRTreeNode uncle = gFather.getLeft();
if (uncle != null && uncle.isBlack() == false) {
// 颜色反转
setBlack(father);
setBlack(uncle);
setRed(gFather);
node = gFather;
continue;
}
if (node == father.getLeft()) {
// 进行右旋旋
rightRotate(father);
// 交换
BRTreeNode tmp = node;
node = father;
father = tmp;
}
setBlack(father);
setRed(gFather);
// 左旋
leftRotate(gFather);
}
}
setBlack(root);
}
/**
* 左旋
* @param node
*/
private void leftRotate(BRTreeNode node) {
BRTreeNode right = node.getRight();
BRTreeNode parent = node.getParent();
// 父节点没有 root
if (parent == null) {
root = right;
right.setParent(null);
} else {
if (parent.getLeft() != null && parent.getLeft() == node) {
parent.setLeft(right);
}else {
parent.setRight(right);
}
right.setParent(parent);
}
node.setParent(right);
node.setRight(right.getLeft());
if (right.getLeft() != null) {
right.getLeft().setParent(node);
}
right.setLeft(node);
}
/**
* 右旋
* @param node
*/
private void rightRotate(BRTreeNode node) {
BRTreeNode left = node.getLeft();
BRTreeNode parent = node.getParent();
if (parent == null) {
root = left;
left.setParent(null);
} else {
if (parent.getLeft() != null && parent.getLeft() == node) {
parent.setLeft(left);
} else {
parent.setRight(left);
}
left.setParent(parent);
}
node.setParent(left);
node.setLeft(left.getRight());
if (left.getRight() != null) {
left.getRight().setParent(node);
}
left.setRight(node);
}
/**
* 设置黑色
* @param node
*/
private void setBlack(BRTreeNode node) {
node.setBlack(true);
}
/**
* 设置红色
* @param node
*/
private void setRed(BRTreeNode node) {
node.setBlack(false);
}
public static void main(String[] args) {
RBTree rbTree = new RBTree();
rbTree.insert(10); // 根节点
rbTree.insert(5);
rbTree.insert(9);
rbTree.insert(3);
rbTree.insert(6);
rbTree.insert(7);
rbTree.insert(19);
rbTree.insert(32);
rbTree.insert(24);
rbTree.list(rbTree.root);
}
}
运行截图