红黑树
红黑树的基本性质和复杂度分析
1.每个节点或者是红色的,或者是黑色的
2.根节点是黑色的
3.每一个叶子节点(最后的空节点)是黑色的
4.如果一个节点是红色的,那么他的孩子节点都是黑色的
5.从任意一个节点到叶子节点,经过的黑色节点是一样的
package com.ffyc.lesson.lesson11;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
public class RBTree<T extends Comparable<T>> {
private class Node<T> {
T val;
Node left;
Node right;
//结点的颜色
boolean isRed;
int count;//统计次数
Node(T val) {
this.val = val;
this.left = this.right = null;
this.isRed = true;//新建的结点是红色
this.count=1;
}
}
//红黑树的特性
private Node<T> root;//根结点
private int size;
//判断是否为空
public boolean isEmpty() {
return this.size == 0;
}
//获取结点的个数
public int getSize() {
return this.size;
}
//获取结点颜色的公共方法
public boolean getNodeColor(Node node){
if (node==null){
return false;
}
return node.isRed;
}
public void add(T val) {
this.root = add(this.root, val);
//更新根结点的颜色
this.root.isRed = false;
}
//向以node为根的红黑树中添加结点v
private Node<T> add(Node<T> node, T v) {
//递归到底的情况
if (node == null) {
this.size++;
return new Node(v);
}
Node result=null;
if (node.val.compareTo(v) > 0) {
node.left = add(node.left, v);
}else if(node.val.compareTo(v)<0){
node.right=add(node.right,v);
}else{
node.count++;
}
result=node;
//对result进行处理
//左旋
if (getNodeColor(result.right)&&!getNodeColor(result.left)){
result=leftRoTate(result);
}
//右旋
if (getNodeColor(result.left)&&getNodeColor(result.left.left)){
result=rightRoTate(result);
}
//颜色翻转
if (getNodeColor(result.left)&&getNodeColor(result.right)){
flipColor(result);
}
return result;
}
public void levelTravel(){
//1.使用队列
Queue<Node> queue=new LinkedList<>();
//2.将根节点放入队列
if (this.root==null){
return;
}
queue.offer(this.root);
//3.循环判断
while (!queue.isEmpty()) { //每次循环从左往右放入节点
Node node = queue.poll();
System.out.println("val:"+node.val+",color:"+(node.isRed?"Red":"Black")+",次数"+node.count);
if (node.left != null) { //左节点放进去
queue.offer(node.left);
}
if (node.right != null) { //又节点放进去
queue.offer(node.right);
}
}
}
//左旋转的代码
public Node leftRoTate(Node node) {
Node x = node.right;
Node t2 = x.left;
node.right=t2;
x.left = node;
//颜色更新
x.isRed = node.isRed;
//node可能是融合结点
node.isRed = true;
return x;
}
//颜色旋转
public void flipColor(Node node) {
node.left.isRed = false;
node.right.isRed = false;
//node可能是融合结点
node.isRed = true;
}
//右旋转的代码
public Node rightRoTate(Node node) {
Node x = node.left;
node.left = x.right;
x.right = node;
//颜色更新
x.isRed = node.isRed;
//node可能是融合结点
node.isRed = true;
return x;
}
public static void main(String[] args) {
RBTree<Integer> rbTree=new RBTree<>();
int[] arr={1,3,5,54,13,12,11,5,24,6,23,6,8,6};
Arrays.stream(arr).forEach(rbTree::add);
System.out.println(rbTree.getSize());
rbTree.levelTravel();
}
}