Java实现红黑树

一、定义

红黑树要么是颗空树,要么是一颗满足以下三点性质的树:

  1. 红色链接必为左链接。
  2. 不存在两条连续的红色链接。
  3. 黑色完美平衡:从任意空链接到根所经历的黑色链接数一样。

二、插入

只存在以下三种情况:

  1. 右节点为红色。左旋。
  2. 右节点为红色,左节点也为红色。颜色反转,左右节点都变黑,当前节点变红。
  3. 右节点为红色,且右节点的子节点也为红色。右旋,然后就变成了情况2。
    在这里插入图片描述
    左旋完整图(上图的左旋不是一颗红黑树,容易误导)补充:
    在这里插入图片描述

总结:两个旋转,一个反转。
最后,根节点一定是黑色(进行操作2时,可能会把根节点变红,要调整!)

三、代码

package algorithm.datastructure;

import java.util.Comparator;

/**
 * created by 吴家俊 on 2021/3/23.
 */
public class RedBlackTree<K,V> {
    private static final boolean RED = true;
    private static final boolean BLACK = false;
    private Node root;
    private Comparator<K> comparator;

    public RedBlackTree(Comparator<K> comparator) {
        this.comparator = comparator;
    }

    public void printOrderly(){
        printOrderly(root);
    }

    private void printOrderly(Node node){
        if (node == null) return;
        printOrderly(node.left);
        System.out.println(node.key);
        printOrderly(node.right);
    }

    class Node{
        K key;
        V value;
        Node left,right;
        int N; //子树中的节点总数
        boolean color;

        public Node(K key, V value, int n, boolean color) {
            this.key = key;
            this.value = value;
            N = n;
            this.color = color;
        }
    }

    private boolean isRed(Node node){
        if (node == null) return false;
        return node.color == RedBlackTree.RED;
    }

    private int size(Node node){//计算当前Node的子节点个数有多少
        if (node==null){
            return 0;
        }
        return node.N;
    }

    private Node rotateLeft(Node node){//将node进行左旋,返回新结点
        Node t = node.right;
        node.right = t.left;
        t.left = node;
        node.N = size(node.left)+size(node.right)+1;
        t.N = size(node) + size(t.right) + 1;
        return t;
    }

    private Node rotateRight(Node node){
        Node t = node.left;
        node.left = t.right;
        t.right = node;
        node.N = size(node.right)+size(node.left)+1;
        t.N = size(node) + size(t.left) + 1;
        return t;
    }

    private void flipColor(Node node){
        node.left.color = BLACK;
        node.right.color = BLACK;
        node.color = RED;
    }

    public void add(K key,V value){
        root = add(key,value,root);
        root.color = BLACK;
    }
    private Node add(K key,V value,Node node){
        if (node == null){
            return new Node(key,value,1,RED);
        }
        int c = comparator.compare(key,node.key);
        if (c < 0) node.left = add(key,value,node.left);
        else if (c > 0) node.right = add(key,value,node.right);
        else node.value = value;

        if(isRed(node.right) && !isRed(node.left)) node = rotateLeft(node);
        if(isRed(node.left) && isRed(node.left.left)) node = rotateRight(node);
        if (isRed(node.left) && isRed(node.right)) flipColor(node);

        node.N = size(node.left)+size(node.right)+1;
        return node;
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值