红黑树的左连接为红连接,右连接为黑连接
红黑树左旋
1.左旋:让x的左子节点变为h的右子节点
h.right = h.left
2.让h成为x的左子节点
x.left = h;
3.让h的color属性变为x的color属性值
x.color = h.color
4.让h的color属性变为red
h.color = true
如果某个节点的左子节点为红色,且左子节点的左子节点也是红色需要右旋
向单个节点插入节点,插入节点小于当前节点
插入节点大于当前节点需要进行右旋
原始的红黑树
向底部的2-节点插入新的键
左旋后
颜色反转后
向一颗双键树中插入新键
1.新键大于原树中的两个键
2.新键大于原树中的一个键小于另一个键
向树底部3-节点插入新键
/**
* @author ming
* @create 2022/6/6
* @description:
*/
public class RedBlackTree<K extends Comparable<K>,V> {
private Node root;
private int N;
public static final boolean RED = true;
public static final boolean BLACK = false;
private class Node{
K key;
V value;
Node left;
Node right;
boolean color;
public Node(K key, V value, Node left, Node right, boolean color) {
this.key = key;
this.value = value;
this.left = left;
this.right = right;
this.color = color;
}
}
public int size(){
return N;
}
/**
* 判断当前节点的父指向链接是否为红色
* @param x
* @return
*/
public boolean isRed(Node x){
if(x==null) return false;
return x.color == RED;
}
//左旋
public Node rotateLeft(Node h){
//获取h节点右子节点表示为x
Node x = h.right;
//让x节点的左子节点成为h节点的右子节点
h.right = x.left;
//让h成为x的左子节点
x.left = h;
//让x节点的color属性等于h节点的color书属性
x.color = h.color;
//让h节点的color属性变为红色
h.color = RED;
return x;
}
public Node roltateRight(Node h){
//获取h节点的左子节点表示x
Node x = h.left;
//x节点的右子节点成为h节点的左子节点
h.left = x.right;
//让h节点成为x节点的右子树
x.right = h;
//让x节点的color属性等于h节点的color属性
x.color = h.color;
//让h节点color为红色
h.color = RED;
return x;
}
//颜色反转
public void flipColors(Node h){
h.color = RED;
h.left.color=BLACK;
h.right.color=BLACK;
}
public void put(K key,V value){
root = put(root,key,value);
root.color = BLACK;
}
private Node put(Node h, K key, V value) {
N++;
if(h==null){
return new Node(key,value,null,null,RED);
}
//比较h节点和key的值
int cmp = key.compareTo(h.key);
if(cmp<0){
h.left = put(h.left,key,value);
}else if(cmp>0){
h.right = put(h.right,key,value);
}else{
h.value = value;
}
//当前节点h的节点左子节点为黑色,h节点的右子树为红色
if(isRed(h.right)&&!isRed(h.left)){
h = rotateLeft(h);
}
//当前节点的左子树的左子树都为红色,则需要进行右旋
if(isRed(h.left)&&isRed(h.left.left)){
h = roltateRight(h);
}
//颜色反转
//当前节点的左子节点和右自己节点都以为红色则尽心颜色反转
if(isRed(h.left)&&isRed(h.right)){
flipColors(h);
}
return h;
}
public V get(K key){
return get(root,key);
}
private V get(Node x, K key) {
if(x==null){
return null;
}
int cmp = key.compareTo(x.key);
if(cmp<0){
return get(x.left,key);
}else if(cmp>0){
return get(x.right,key);
}else {
return x.value;
}
}
public static void main(String[] args) {
RedBlackTree<String, String> tree = new RedBlackTree<>();
tree.put("1","张三");
tree.put("2","李四");
tree.put("3","王五");
//从树中获取元素
String r1 = tree.get("1");
System.out.println(r1);
String r2 = tree.get("2");
System.out.println(r2);
String r3 = tree.get("3");
System.out.println(r3);
}
}