直接看代码注释
package com.zzqfsy.algorithm.redblacktree;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 1. 红黑树的特点
* 每个结点不是红色就是黑色。
* 不可能有连在一起的红色结点。
* 根结点一定为黑色。
* 每个红色结点的两个子结点都是黑色。
* <p>
* 2. 旋转与颜色变换规则
* 2.1 颜色变换
* 当前结点的父亲是红色,且叔叔结点也是红色时:
* <p>
* 把父结点设为黑色
* 把叔叔结点设为黑色
* 把爷爷结点设为红色
* 把指针定义到爷爷结点上,当有违红黑树和特点时再进行变色或旋转
*/
public class RedBlackTree {
public static void main(String[] args) {
RedBlackTree redBlackTree = new RedBlackTree();
redBlackTree.insert(3);
redBlackTree.insert(10);
redBlackTree.insert(6);
redBlackTree.insert(1);
redBlackTree.insert(5);
redBlackTree.insert(4);
redBlackTree.insert(4);
redBlackTree.insert(4);
redBlackTree.insert(12);
// for (int i = 0; i < 100; i++) {
redBlackTree.insert(15);
// }
System.out.println("Root:" + redBlackTree.getRoot());
System.out.println(redBlackTree.getBeforeList(redBlackTree));
}
/**
* 红色
*/
private final int RED = 0;
/**
* 黑色
*/
private final int BLACK = 1;
/**
* 根结点
*/
private Node root;
/**
* 内部类表示结点
*/
private class Node {
int data;
int color;
Node left;
Node right;
Node parent;
Node(int data) {
this.data = data;
color = RED;
}
public int height(){
return Math.max(left == null ? 0 : left.height(),
right == null ? 0 : right.height()) + 1;
}
@Override
public String toString() {
return "Node{data=" + data + ", color=" + (color == RED ? "red" : "black") + '}';
}
}
/**
* 获取Node结点
*/
public Node getInstanceNode(int data) {
return new Node(data);
}
/**
* 插入值
*
* @param data 数值
*/
public void insert(int data) {
// region insert node
Node node = new Node(data);
//插入根结点
if (root == null) {
node.color = BLACK;
root = node;
return;
}
Node parent = root;
Node son;
//左子树
if (data < parent.data) {
son = parent.left;
} else {
son = parent.right;
}
//递归
while (son != null) {
parent = son;
if (data < parent.data) {
son = parent.left;
} else {
son = parent.right;
}
}
if (data < parent.data) {
parent.left = node;
} else {
parent.right = node;
}
node.parent = parent;
// endregion
//颜色变换
colorConvert(node);
}
/**
* 颜色变换,使整体符合红黑树规则
*/
public void colorConvert(Node node) {
Node parent;
Node grandpa;
//当父结点不为空且颜色为红色(插入节点都为红色,保证没有连续连接的红色节点来消除高度)
while ((parent = node.parent) != null && parent.color == RED) {
grandpa = parent.parent;
//如果父亲是爷爷的左子树
if (grandpa.left == parent) {
//获取叔叔结点
Node uncle = grandpa.right;
//如果叔叔结点不为空且颜色为红色
if (uncle != null && uncle.color == RED) {
// 颜色标级,父一级为黑色,祖父为红色
parent.color = BLACK;
uncle.color = BLACK;
grandpa.color = RED;
node = grandpa;
continue;
}
if (node == parent.right) {
//左旋
leftRotate(parent);
//左旋后父子身份互换
Node temp = node;
node = parent;
parent = temp;
}
// 颜色标级,父一级为黑色,祖父为红色
parent.color = BLACK;
grandpa.color = RED;
//右旋
rightRotate(grandpa);
} else {
//如果父亲是爷爷的右子树
Node uncle = grandpa.left;
if (uncle != null && uncle.color == RED) {
// 颜色标级,父一级为黑色,祖父为红色
parent.color = BLACK;
uncle.color = BLACK;
grandpa.color = RED;
node = grandpa;
continue;
}
if (node == parent.left) {
//右旋
rightRotate(parent);
//右旋后父子身份互换
Node temp = node;
node = parent;
parent = temp;
}
// 颜色标级,父一级为黑色,祖父为红色
parent.color = BLACK;
grandpa.color = RED;
//左旋
leftRotate(grandpa);
}
}
root.color = BLACK;
}
/**
* 左旋
*/
private void leftRotate(Node node) {
Node right = node.right;
Node parent = node.parent;
// — (左旋处理爸爸,【父亲节点】的父亲为【祖父节点】的父亲)
if (parent == null) {
root = right;
right.parent = null;
} else {
if (parent.left != null && parent.left == node) {
parent.left = right;
} else {
parent.right = right;
}
right.parent = parent;
}
// ——(左旋处理孩子,【父亲节点】的左节点为【祖父节点】的右节点)
node.right = right.left;
if (right.left != null) {
right.left.parent = node;
}
// ——(左旋处理自身,【父亲节点】的左节点为【祖父节点】)
node.parent = right;
right.left = node;
}
/**
* 右旋
*/
private void rightRotate(Node node) {
Node left = node.left;
Node parent = node.parent;
// — (右旋处理爸爸,【父亲节点】的父亲为【祖父节点】的父亲)
if (parent == null) {
root = left;
left.parent = null;
} else {
if (parent.left != null && parent.left == node) {
parent.left = left;
} else {
parent.right = left;
}
left.parent = parent;
}
// ——(右旋处理孩子,【父亲节点】的右节点为【祖父节点】的左节点)
node.left = left.right;
if (left.right != null) {
left.right.parent = node;
}
// ——(右旋处理自身,【父亲节点】的右节点为【祖父节点】)
node.parent = left;
left.right = node;
}
private Map<Integer, List<String>> beforeListMap = new HashMap<>();
/**
* 前序遍历
*/
private void beforeTraversal(Node node, int deep) {
if (node != null) {
List<String> beforeList = beforeListMap.get(deep);
if (beforeList == null || beforeList.isEmpty()){
beforeList = new ArrayList<>();
}
beforeList.add(node.data + "-" + (node.color == RED ? "red" : "black") + "-" + node.height() + "-" + deep);
beforeListMap.put(deep, beforeList);
deep = deep + 1;
beforeTraversal(node.left, deep);
beforeTraversal(node.right, deep);
}
}
/**
* 获取前序遍历后的集合
*/
public Map<Integer, List<String>> getBeforeList(RedBlackTree tree) {
tree.beforeTraversal(tree.getRoot(), 0);
return beforeListMap;
}
public Node getRoot() {
return root;
}
}