HashMap源码详解03-红黑树全部代码

这篇博客详细介绍了HashMap中红黑树的源码,重点讨论了插入和删除操作。提供了完整的红黑树代码、打印代码及测试代码,读者可以通过运行RBTreeTest进行验证。
摘要由CSDN通过智能技术生成

红黑树代码只实现了插入和删除,查找与二叉查找树相同。直接运行RBTreeTest即可测试红黑树。

红黑树代码

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

    private static final boolean RED = true;
    private static final boolean BLACK = false;

    private Node<T> root;

    public Node<T> getRoot() {
   
        return root;
    }

    public void insert(T key) {
   
        // 根节点,直接插入
        if (root == null) {
   
            root = new Node<>(key);
        } else {
   
            // 当前循环节点
            Node<T> x = root;
            // 最后一个循环的节点
            Node<T> p = x;
            while (x != null) {
   
                p = x;
                int tmp = key.compareTo(x.key);
                // key比x大,插入到右子树
                if (tmp > 0) {
   
                    x = x.right;
                } else if (tmp < 0) {
   
                    // key比x小,插入到左子树
                    x = x.left;
                } else {
   
                    // 相等节点进行替换,只不过目前没有不需要设置值,直接返回
                    return;
                }
            }
            // p为待插入节点的父节点
            Node<T> node = new Node<>(key);
            if (key.compareTo(p.key) > 0) {
   
                p.right = node;
            } else {
   
                p.left = node;
            }
            node.parent = p;
            // 进行插入平衡
            insertBalance(node);
        }
        // 根节点染黑
        setBlack(root);
    }

    private void insertBalance(Node<T> x) {
   
        for (; ; ) {
   
            // 情景1:x节点为root,直接返回
            if (parentOf(x) == null) {
   
                root = x;
                return;
            }

            // 情景2:父节点是黑色 ==> 不用处理
            if (isBlack(parentOf(x))) {
   
                return;
            }
            // 情景3:父节点是红色,叔节点是红色 ==> 父节点和叔节点变成黑色,祖父节点变红,x指向祖父节点
            if (isRed(uncleOf(x))) {
   
                setBlack(parentOf(x));
                setBlack(uncleOf(x));
                setRed(gParentOf(x));
                x = gParentOf(x);
            }
            // 情景4:父节点红色,叔节点黑色
            else {
   
                // p是祖父节点的左子节点
                if (parentOf(x) == gParentOf(x).left) {
   
                    // 情景4.1:x是p的右子节点
                    if (x == parentOf(x).right) {
   
                        // 以p为节点进行左旋,并且x指向p
                        rotateLeft(x = parentOf(x));
                    }
                    // 情景4.2:x是p的左子节点 => p变黑,x祖父变红,祖父右旋
                    setBlack(parentOf(x));
                    setRed(gParentOf(x));
                    rotateRight(gParentOf(x));
                } else {
   
                    // p是祖父节点的右子节点
                    // 情景4.1:x是p的左子节点
                    if (x == parentOf(x).left) {
   
                        // 以p为节点进行右旋,并且x指向p
                        rotateRight(x = parentOf(x));
                    }
                    // 情景4.2:x是p的右子节点 => p变黑,x祖父变红,祖父左旋
                    setBlack(parentOf(x));
                    setRed(gParentOf(x));
                    rotateLeft(gParentOf(x));
                }
            }
        }
    }

    public void delete(T key) {
   
        // 指向待删除节点
        Node<T> x = root;
        while (x != null) {
   
            int tmp = key.compareTo(x.key);
            if (tmp > 0)</
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值