java算法-红黑树的增删查改

package chapter4;

public class BRT<key extends Comparable<key>, value> {

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

    private Node root;


    private class Node{
        private Node left, right;
        private Boolean color;
        private int N;
        private key key;
        private value value;

        public Node(key key, value value, Node left, Node right, Boolean color, int n){
            this.color = color;
            this.left = left;
            this.right = right;
            this.N = n;
            this.key = key;
            this.value = value;
        }
    }

    public int size(Node h){
        if(h == null)
            return 0;
        return h.N;
    }

    //left rotate
    private Node rotateLeft(Node h){
        Node temp = h.right;
        h.right = temp.left;
        temp.left = h;
        //exchange color
        temp.color = h.color;
        h.color = RED;
        h.N = size(h.left) + size(h.right) + 1;
        return temp;
    }


    //right rotate
    private Node rotateRight(Node h){
        Node temp = h.left;
        h.left = temp.right;
        temp.right = h;
        //exchange color
        temp.color = h.color;
        h.color = RED;
        h.N = size(h.left) + size(h.right) + 1;
        return temp;
    }

    //change color when two node are red
    private void flipColor(Node node){
        node.left.color = BLACK;
        node.right.color = BLACK;
        node.color = RED;
    }


    //change color when two node are red
    private void flipColor2(Node node){
        node.left.color = !node.left.color;
        node.right.color = !node.right.color;
        node.color = !node.color;
    }

    //get, like the binary search tree
    public Node get(key key){
        return get(key, this.root);
    }

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

    private Node get(key key, Node node){
        if(node == null)
            return null;
        int com = node.key.compareTo(key);
        if (com == 0)
            return node;
        else if (com < 0)
            return get(key, node.left);
        else
            return get(key, node.right);
    }

    //put
    public void put(key key, value value){
        put(key, value, this.root);
    }

    private Node put(key key, value value, Node node){
        if(node == null){
            Node newNode = new Node(key, value, null, null, RED, 1);
            return newNode;
        }
        int com = node.key.compareTo(key);
        if (com == 0){
            node.value = value;
        }
        else if (com < 0)
             node.left = put(key, value, node.left);
        else
             node.right = put(key, value, node.right);

        //balance to 2-3 node
        if(!isRed(node.left) && isRed(node.right))
            node = rotateLeft(node);
        if( isRed(node) && isRed(node.left))
            node = rotateRight(node);
        //both two red node
        if(isRed(node.right) && isRed(node.left))
            flipColor(node);
        node.N = size(node.left) + size(node.right) +1;
        return node;
    }


    public void deleteMin(){

        if(!isRed(this.root))
            this.root.color = !this.root.color;
        this.root = deleteMin(this.root);
        if(isRed(this.root))
            this.root.color = BLACK;
    }

    private Node deleteMin(Node node){
        if(node.left == null)
            return null;
        if(!isRed(node.left)&&!isRed(node.left.left)){
            node = moveLeft(node);
        }

        node.left = deleteMin(node.left);

        //balance to 2-3 node
        if(!isRed(node.left) && isRed(node.right))
            node = rotateLeft(node);
        if( isRed(node) && isRed(node.left))
            node = rotateRight(node);
        //both two red node
        if(isRed(node.right) && isRed(node.left))
            flipColor(node);
        node.N = size(node.left) + size(node.right) +1;
        return node;
    }

    private Node moveLeft(Node node){
        flipColor2(node);
        if(isRed(node.right.left)){
            node.right = rotateRight(node.right);
            node = rotateLeft(node);
        }
        return node;
    }

    private Node moveRight(Node node){
        flipColor2(node);
        if(isRed(node.right.left)){
            node = rotateLeft(node);
        }
        return node;
    }

    //delete

    public void delete(key key){
        this.root = delete(key, this.root);
    }

    private Node min(Node node){
        if (node.left == null){
            return node;
        }
        return min(node.left);
    }
    private Node delete(key key, Node node){
        if(key.compareTo(node.key) < 0){
            //keep delete node is 3-node or 4-node in left tree
            if(!isRed(node.left) && !isRed(node.left.left)){
                node = moveLeft(node);
            }
            node.left = delete(key, node.left);
        }else{
            if(isRed(node.left)){
                rotateRight(node);
            }

            if(key.compareTo(node.key) == 0 && node.right == null){
                return null;
            }

            if(key.compareTo(node.key) == 0){
                Node minNode = min(node.right);
                node.key = minNode.key;
                node.value = minNode.value;
                node.right = deleteMin(node.right);
            }else {
                //keep delete node is 3-node or 4-node in right tree
                if(!isRed(node.right) && !isRed(node.right.left)){
                    node = moveRight(node);
                }
                node.right = delete(key, node.right);
            }
        }
        //balance to 2-3 node
        if(!isRed(node.left) && isRed(node.right))
            node = rotateLeft(node);
        if( isRed(node) && isRed(node.left))
            node = rotateRight(node);
        //both two red node
        if(isRed(node.right) && isRed(node.left))
            flipColor(node);
        node.N = size(node.left) + size(node.right) +1;
        return node;
    }
}

红黑树利用颜色增加了3-节点的用法,使得每个路径的到叶节点(包括黑色节点)的距离都相同,大大减少了树的深度,加快了数据的插入和查找。

理解红黑树的算法是再二分查找树的基础上增加了颜色的属性、旋转操作和平衡操作。

其中平衡的原理就是根据不同情况的节点的颜色情况,向上递归时,对2-3节点进行平衡操作

删除操作时最难的,先要掌握删除最小值和最小值操作(最小值和最大值删除时需要再一个3或者4节点上,递归时一直要保持),然后再删除最小值(左树返回空时),最后复原。

掌握了删除最小值和最大值后再去理解删除操作,会更简单一些。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值