红黑树实现

这篇博客详细介绍了红黑树的概念,包括其特性、平衡调整方法(左旋、右旋、颜色反转)以及插入操作的实现。通过代码展示了红黑树节点的插入过程,并提供了测试用例。红黑树是一种自平衡的二叉查找树,能够保证查找、插入和删除操作的时间复杂度稳定在O(log n)。
摘要由CSDN通过智能技术生成

前言

红黑树的基本思想是用标准的二叉查找树和一些额外的信息(替换3-结点)来表示2-3树。树中的链接分为两种类型:

红链接:将两个2-结点连接起来构成一个3-结点。

黑链接:则是2-3树中的普通链接。

红黑树的定义

红黑树是含有红黑链接并满足下列条件的二叉查找树:

1、红链接均为左链接

2、没有任何一个结点同时和两条红链接相连

3、该树是完美黑色平衡的,即任意空链接到根结点的路径上的黑链接数量相同。

平衡化

左旋

当某个结点的左子结点为黑色,右子结点为红色,此时需要左旋。

 前提:当前结点为h,它的右子结点为x;

左旋过程:

1、让x的左子结点变为h的右子结点:h.right = x.left;

2、让h成为x的左子结点:x.left = h;

3、让h的color属性变为x的color属性:x.color=h.color;

4、让h的color属性变为red: h.color = true;

右旋

当某个结点的左子结点是红色,且左子结点的左子结点也是红色,需要右旋

前提:当前结点为h,它的左子结点为x;

右旋过程:

1、让x的右子结点称为h的左子结点 : h.left = x.right

2、让h称为x的右子结点:x.right = h

3、让x的color变为h的color属性值: x.color = h.color

4、让h的color为red

颜色反转

当一个结点的左子结点和右子结点的color都为red的时候,也就是出现了临时4-结点,此时只需要把左右子结点变为black,同时让当前结点颜色变为red即可。

代码实现


public class RedBlackTree<k extends Comparable,v> {

    private Node<k,v> root;
    private int size;
    private static  final boolean RED = true;
    private static  final boolean BLACK = false;


    //判断当前结点的父指向链接是否为红色
    private boolean isRed(Node x){
        if (x==null){
            return RED;
        }
        return x.color==RED;
    }

    //左旋调整
    private Node rotateLeft(Node h){
        Node x = h.left;
//      1、让x的左子结点变为h的右子结点
        h.right = x.left;
//      2、让h成为x的左子结点;
        x.left = h;
//      3、让h的color属性变为x的color属性:x.color=h.color;
        x.color = h.color;
//        4、让h的color属性变为red
        h.color=RED;
        return x;
    }


    //右旋调整
    private Node rotateRight(Node h){
        Node x = h.left;
//        1、让x的右子结点称为h的左子结点
        h.left = x.right;
//        2、让h称为x的右子结点
        x.right = h;
//        3、让x的color变为h的color属性值:
        x.color = h.color;
//        4、让h的color为red
        h.color=RED;
        return x;
    }

    //颜色调整
    private void flipColors(Node h){
        if (h==null){
            return;
        }
        if (h.left!=null){
            h.left.color = BLACK;
        }
        if (h.right!=null){
            h.right.color = BLACK;
        }
        h.color = RED;
    }

    //在整个树上完成插入操作
    public void put(k key,v value){
        root = put(root,key,value);
        //确保根结点是黑色
        root.color=BLACK;
    }

    //在指定树x上完成插入操作
    private Node put(Node<k,v> h,k key,v value){
        if (h==null){
            size++;
            return new Node(key,value,null,null,RED);
        }
        int com = key.compareTo(h.key);
        if (com<0){
            h.left = put(h.left,key,value);
        }else if (com>0){
            h.right = put(h.right,key,value);
        }else {
            h.value = value;
        }

        if (!isRed(h.left)&&isRed(h.right)){
           h = rotateLeft(h);
        }
        if (h.left!=null&&isRed(h.left)&&isRed(h.left.left)){
           h = rotateRight(h);
        }
        flipColors(h);
       return h;
    }

    //根据key,从树中找出对应的值
    public v get(k key){
        return get(root,key);
    }

    //根据key,从指定树x中找出对应的值
    private v get(Node<k,v> h,k key){
        if (h==null){
            return null;
        }

        int com = key.compareTo(h.key);
        if (com>0){
            return get(h.right,key);
        }else if (com<0){
            return get(h.left,key);
        }else {
            return h.value;
        }
    }

    public int size(){
        return size;
    }


    private class Node<k,v>{
         k key;
         v value;
         Node<k,v> left;
         Node<k,v> right;
         boolean  color;//由其父结点指向它的链接的颜色

        public Node(k key, v value, Node<k, v> left, Node<k, v> right, boolean color) {
            this.key = key;
            this.value = value;
            this.left = left;
            this.right = right;
            this.color = color;
        }
    }

}

 测试


    public static void main(String[] args) {

        RedBlackTree<Integer, String> tr = new RedBlackTree<>();
        tr.put(1,"hhh");
        tr.put(2,"ccc");
        tr.put(3,"bbb");

        System.out.println(tr.get(1));
        System.out.println(tr.get(2));
        System.out.println(tr.get(3));

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值