2-3树—>红黑树【java实现】

一、2-3树

节点可以存放一个元素或两个元素,因此孩子节点可以为两个或三个

 已添加数组【24 51 11 23 47 62 41 9 85 19 53 13 17 50】为例:

分裂 

融合 

添加完成后的2-3树,将将出现三节点的左边记为红色,下来就可以向左下拉变成红黑树了。

 

下拉后变为一棵红黑树

 

二、红黑树

红黑树的五大特点:

1.节点不是黑色就是红色

2.根节点是黑色

3.叶子结点是(null)黑色

4.红色节点的孩子节点一定都是黑色节点

5.根节点到任意叶子结点的黑色节点的数目相同

红黑树的添加操作 :

添加时需要调整的五种情况

 

java代码实现: 

//红黑树

import java.util.Arrays;

public class RBTree<T extends Comparable<T>> {

    public class Node {
        T val;
        Node left;
        Node right;
        //红节点
        boolean isRed;
        //统计单词出现的次数
        int count;

        public Node(T val) {
            this.val = val;
            //默认为红节点
            this.isRed = true;
            this.count = 1;
        }

        @Override
        public String toString() {
            return String.format("val:%s,color:%s,count:%d", this.val, this.isRed ? "Red" : "Black", this.count);
        }
    }

    private Node root;
    private Integer size;

    public RBTree() {
        this.root = null;
        this.size = 0;
    }

    public boolean isEmpt() {
        return this.size == 0;
    }

    public Integer getSize() {
        return this.size;
    }

    //改变颜色
    public void changeColor(Node x) {
        x.isRed = true;
        x.right.isRed = false;
        x.left.isRed = false;
    }
    
    //左旋转
    public Node leftSpin(Node x) {
        Node y = x.right;
        Node t2 = y.left;

        x.right = t2;
        y.left = x;
        y.isRed = x.isRed;
        x.isRed = true;
        return y;
    }

    //右旋转
    public Node rightSpin(Node x) {
        Node y = x.left;
        Node t2 = y.right;

        x.left = t2;
        y.right = x;

        y.isRed = x.isRed;
        x.isRed = true;
        return y;
    }

    public boolean isRed(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;
    }

    private Node add(Node node, T val) {
        if (node == null) {
            this.size++;
            Node leafNode = new Node(val);
            return leafNode;
        }
        //当前节点的值小于添加的val,因此val做右孩子
        if (node.val.compareTo(val) < 0) {
            node.right = add(node.right, val);
        } else if (node.val.compareTo(val) > 0) {
            node.left = add(node.left, val);
        } else {
            node.count++;
        }

        //添加后还要判断是否是平衡二叉树
        Node resNode = node;
        //左旋
        if (isRed(resNode.right) && !isRed(resNode.left)) {
            resNode = leftSpin(resNode);
        }
        //右旋
        if (isRed(resNode.left) && isRed(resNode.left.left)) {
            resNode = rightSpin(resNode);
        }
        //颜色反转
        if (isRed(resNode.left) && isRed(resNode.right)) {
            changeColor(resNode);
        }
        return resNode;
    }

    public static void main(String[] args) {
        RBTree<Integer> bst = new RBTree<>();
        int[] res = {24, 51, 11, 23, 47, 62, 41, 9, 85, 19, 53, 13, 17, 50};
        Arrays.stream(res).forEach(bst::add);
        System.out.println("------");
    }
}

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小俱的一步步

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值