简析红黑树

红黑树节点

  • public class RbTreeNode {
          
          
    
        /** 节点颜色 */
        public boolean color;
    
        /** 左孩子 */
        public RbTreeNode left;
    
        /** 右孩子 */
        public RbTreeNode right;
    
        public int value;
    
        /** 父节点 */
        public RbTreeNode parent;
    
        public RbTreeNode(int v){
          
          
            this.value = v;
            left = null;
            right = null;
            parent = null;
        }
    }
    

红黑树插入删除相关

  • public class RbTree {
          
          
    
        /** 根节点 */
        RbTreeNode root;
    
        public RbTree(RbTreeNode root){
          
          
            this.root = root;
        }
    
        /** 递归寻找指定值 */
        public RbTreeNode searchRecursively(RbTreeNode root, int v){
          
          
            if (root == null){
          
          
                return null;
            }
    
            if (v>root.value){
          
          
                return searchRecursively(root.right, v);
            } else if (v<root.value){
          
          
                return searchRecursively(root.left,v);
            } else {
          
          
                return root;
            }
        }
    
        /** 递归插入新节点 */
        public boolean insertRecursively(RbTreeNode root, RbTreeNode newNode){
          
          
            /** 插入到根节点 */
            if (root == null){
          
          
                root = newNode;
                return true;
            }
    
            /** 插入到根节点的右孩子 */
            if (newNode.value>root.value){
          
          
                if (root.right==null){
          
          
                    root.right = newNode;
                    newNode.parent = root;
    
                    /**
                     * 新插入的节点都着色为红色,这样只可能违背红黑树五条原则中的第四条
                     * seg.如果一个节点是红色,则他的子节点必须是黑色
                     */
                    newNode.color = false;
    
                    /**
                     * 通过着色和旋转操作,使之恢复成一颗红黑树
                     */
                    insertFixUp(newNode);
    
                    return true;
                } else {
          
          
                    return insertRecursively(root.right,newNode);
                }
            }
            /** 插入到根节点的左孩子 */
            else if (newNode.value<root.value){
          
          
                if (root.left == null){
          
          
                    root.left = newNode;
                    newNode.parent = root;
    
                    /**
                     * 新插入的节点都着色为红色,这样只可能违背红黑树五条原则中的第四条
                     * seg.如果一个节点是红色,则他的子节点必须是黑色
                     */
                    newNode.color = false;
    
                    /**
                     * 通过着色和旋转操作,使之恢复成一颗红黑树
                     */
                    insertFixUp(newNode);
    
                    return true;
                } else {
          
          
                    return insertRecursively(root.left,newNode);
                }
            }
            /** 已存在 */
            else {
          
          
                return false;
            }
        }
    
        /** 递归删除 */
        public void deleteRecursively(RbTreeNode root, int v){
          
          
            if (root == null){
          
          
                return;
            }
    
            if (root.value>v){
          
          
                deleteRecursively(root.left,v);
            } else if (root.value<v){
          
          
                deleteRecursively(root.right,v);
            } else {
          
          
                if (root.right == null && root.left == null){
          
          
                    RbTreeNode parent = root.parent;
                    if (parent.left == root){
          
          
                        parent.left = null;
                        return;
                    }
                    if (parent.right == root){
          
          
                        parent.right = null;
                        return;
                    }
                    root.parent = null;
                    return;
                } else if (root.right == null){
          
          
                    RbTreeNode left = root.left;
                    int val = left.value;
    
                    root.left = left.left;
                    root.right = left.right;
                    root.value = val;
    
                    if (left.left!=null){
          
          
                        left.left.parent = root;
                    }
                    if (left.right!=null){
          
          
                        left.right.parent = root;
                    }
                } else if (root.left == null){
          
          
                    RbTreeNode right = root.right;
                    int val = right.value;
    
                    root.left = right.left;
                    root.right = right.right;
                    root.value = val;
    
                    if (right.left!=null){
          
          
                        right.left.parent = root;
                    }
                    if (right.right!=null){
          
          
                        right.right.parent = root;
                    }
                } else {
          
          
                    RbTreeNode node = root.left;
                    while(node.right!=null){
          
          
                        node = node.right;
                    }
    
                    root.value = node.value;
                    deleteRecursively(node,node.value);
                }
            }
        }
    
    
    
        /****************************红黑树相关*****************************/
    
        private RbTreeNode parentOf(RbTreeNode node){
          
          
            return node!=null?node.parent:null;
        }
    
        private boolean colorOf(RbTreeNode node){
          
          
            return node!=null?node.color:true;
        }
    
        private boolean isRed(RbTreeNode node){
          
          
            return (node!=null && node.color==false)?true:false;
        }
    
        private boolean isBlack(RbTreeNode node){
          
          
            return (node!=null && node.color==true)?true:false;
        }
    
        private void setRed(RbTreeNode node){
          
          
            if (node !=null){
          
          
                node.color = false;
            }
        }
    
        private void setBlack(RbTreeNode node){
          
          
            if (node !=null){
          
          
                node.color = true;
            }
        }
    
        private void setParent(RbTreeNode node, RbTreeNode parent){
          
          
            if (node!=null){
          
          
                node.parent = parent;
            }
        }
    
        private void setColor(RbTreeNode node, boolean color){
          
          
            if (node!=null){
          
          
                node.color = color;
            }
        }
    
        /** 左旋 */
        private void leftRotate(RbTreeNode pNode){
          
          
            RbTreeNode right = pNode.right;
            RbTreeNode rightLeft = right.left;
    
            pNode.right = rightLeft;
            if (rightLeft != null){
          
          
                rightLeft.parent = pNode;
            }
    
            right.parent = pNode.parent;
            if (pNode.parent == null){
          
          
                this.root = right;
            } else {
          
          
                if (pNode.parent.left == pNode){
          
          
                    pNode.parent.left = right;
                } else {
          
          
                    pNode.parent.right = right;
                }
            }
    
            right.left = pNode;
            pNode.parent = right;
        }
    
        /** 右旋 */
        private void rightRotate(RbTreeNode pNode){
          
          
            RbTreeNode left = pNode.left;
            RbTreeNode leftRight = left.right;
    
            pNode.left = leftRight;
            if (leftRight != null){
          
          
                leftRight.parent = pNode;
            }
    
            left.parent = pNode.parent;
            if (pNode.parent == null){
          
          
                this.root = left;
            } else {
          
          
                if (pNode.parent.left == pNode){
          
          
                    pNode.parent.left = left;
                } else {
          
          
                    pNode.parent.right = left;
                }
            }
    
            left.right = pNode;
            pNode.parent = left;
        }
    
        private void insertFixUp(RbTreeNode node){
          
          
    
            /**
             * case 1:修正节点是根节点,直接设置成黑色
             */
            if (node == root){
          
          
                setBlack(root);
                return;
            }
    
            /**
             * case 2:如果修正节点的父节点是黑色,则什么都不用做
             */
            if ((parentOf(node)!=null) && (isBlack(parentOf(node)))) {
          
          
                return;
            }
    
    
            RbTreeNode parent;
            RbTreeNode gparent;
    
            /**
             * case 3:修正节点的父节点是红色
             */
            while((parent = (parentOf(node))) != null && isRed(parent)) {
          
          
                gparent = parentOf(parent);
    
                /** 祖父节点是空,则说明当前父亲节点已是根节点 */
                if(gparent == null){
          
          
                    setBlack(parent);
                    break;
                }
    
                /** 父亲节点是祖父节点的左孩子 */
                if (parent == gparent.left){
          
          
                    RbTreeNode uncle = gparent.right;
    
                    /**
                     * case 3.1:当前节点的叔叔节点是红色
                     */
                    if (uncle != null && isRed(uncle)) {
          
          
                        setBlack(uncle);
                        setBlack(parent);
                        setRed(gparent);
                        node = gparent;
                        continue;
                    }
    
                    /**
                     * case 3.2:当前节点的叔叔节点是黑色,并且当前节点是其父节点的右孩子
                     */
                    if (uncle != null && isBlack(uncle) && parent.right == node){
          
          
                        leftRotate(parent);
                        node = parent;
                        continue;
                    }
    
                    /**
                     * case 3.3:当前节点的叔叔节点是黑色,并且当前节点是其父节点的左孩子
                     */
                    if (uncle != null && isBlack(uncle) && parent.left == node){
          
          
                        setBlack(parent);
                        setRed(gparent);
                        rightRotate(gparent);
                        continue;
                    }
                }
                /** 父亲节点是祖父节点的右孩子 */
                else {
          
          
                    RbTreeNode uncle = gparent.left;
    
                    /**
                     * case 3.1:当前节点的叔叔节点是红色
                     */
                    if (uncle != null && isRed(uncle)) {
          
          
                        setBlack(uncle);
                        setBlack(parent);
                        setRed(gparent);
                        node = gparent;
                        continue;
                    }
    
                    /**
                     * case 3.2:当前节点的叔叔节点是黑色,并且当前节点是其父节点的左孩子
                     */
                    if (uncle != null && isBlack(uncle) && parent.left == node){
          
          
                        rightRotate(parent);
                        node = parent;
                        continue;
                    }
    
                    /**
                     * case 3.3:当前节点的叔叔节点是黑色,并且当前节点是其父节点的右孩子
                     */
                    if (uncle != null && isBlack(uncle) && parent.right == node){
          
          
                        setBlack(parent);
                        setRed(gparent);
                        leftRotate(gparent);
                        continue;
                    }
                }
    
    
    
            }
        }
    
        /** 删除节点为key的值 */
        public void remove0(int key){
          
          
            RbTreeNode node;
    
    
            if ((node = (searchRecursively(this.root,key))) != null){
          
          
                remove(node);
            }
        }
    
        /** 删除节点为node的节点 */
        public void remove(RbTreeNode node){
          
          
            /** 被删除的节点左右孩子都不为空 */
            if (node.right != null && node.left != null){
          
          
                removeNodeWithDoubleChild(node);
            }
            /** 被删除节点的右孩子不为空 */
            else if (node.right != null){
          
          
                removeNodeWithRightChild(node);
            }
            /** 被删除节点的左孩子不为空 */
            else if (node.left != null){
          
          
                removeNodeWithLeftChild(node);
            }
            /** 被删除节点的左右孩子都为空 */
            else {
          
          
                removeNodeWithNoChild(node);
            }
        }
    
    
        private void removeNodeWithDoubleChild(RbTreeNode node){
          
          
    
            RbTreeNode replace = node.right;
            while(replace.left != null){
          
          
                replace = replace.left;
            }
    
    
            node.value = replace.value;
            remove(replace);
            return;
        }
    
    
        private void removeNodeWithRightChild(RbTreeNode node){
          
          
    
            RbTreeNode right = node.right;
            RbTreeNode parent = node.parent;
    
            if (parent != null) {
          
          
                if (parent.left == node){
          
          
                    parent.left = right;
                } else {
          
          
                    parent.right = right;
                }
            } else {
          
          
                if (parent.left == node){
          
          
                    parent.left = right;
                    right.parent = parent;
                } else {
          
          
                    parent.right = right;
                    right.parent = parent;
                }
            }
    
            /** 如果删除节点是黑色,需要通过旋转和着色修正成红黑树 */
            if (node.color == false) {
          
          
                removeFixUp(right, parent);
            }
    
        }
    
        private void removeNodeWithLeftChild(RbTreeNode node){
          
          
            RbTreeNode left = node.left;
            RbTreeNode parent = node.parent;
    
            if (parent != null) {
          
          
                if (parent.left == node){
          
          
                    parent.left = left;
                } else {
          
          
                    parent.right = left;
                }
            } else {
          
          
                if (parent.left == node){
          
          
                    parent.left = left;
                    left.parent = parent;
                } else {
          
          
                    parent.right = left;
                    left.parent = parent;
                }
            }
    
            /** 如果删除节点是黑色,需要通过旋转和着色修正成红黑树 */
            if (node.color == false) {
          
          
                removeFixUp(left, parent);
            }
        }
    
        private void removeNodeWithNoChild(RbTreeNode node){
          
          
    
            RbTreeNode parent = parentOf(node);
    
            if (parent != null){
          
          
                if (parent.left == node){
          
          
                    parent.left = null;
                } else {
          
          
                    parent.right = null;
                }
            } else {
          
          
                this.root = null;
            }
        }
    
        /**
         * 将删除节点的子节点在原有颜色基础上,再加一层黑色
         */
        private void removeFixUp(RbTreeNode child, RbTreeNode parent){
          
          
    
            /**
             * case 1:原先子节点为红色
             */
            if (child != null && isRed(child)) {
          
          
                setBlack(child);
                return;
            }
    
            /**
             * case 2:原先子节点为黑色,并且是根节点
             */
            if (child != null && isBlack(child) && child == this.root){
          
          
                // 不用处理
                return;
            }
    
            /**
             * case 3:原先子节点为黑色,并且不是根节点
             */
            while (child != null && isBlack(child) && child != this.root){
          
          
    
                if (parentOf(child) == null){
          
          
                    break;
                }
    
    
                /** 当前节点是其父节点的左孩子 */
                if (parent.left == child) {
          
          
    
                    RbTreeNode other = parent.right;
    
                    /**
                     * case 3.1:删除节点位置新节点的兄弟节点是红色
                     */
                    if (isRed(other)) {
          
          
                        setBlack(other);
                        setRed(parent);
                        leftRotate(parent);
                        parent = child.parent;
                        continue;
                    }
    
                    /**
                     * case 3.2:兄弟节点的子节点只要存在,必须是黑色,无论1个还是两个
                     */
                    if (other.left == null || isBlack(other.left) && (other.right == null || isBlack(other.right))) {
          
          
                        setRed(other);
                        child = parent;
                        parent = parentOf(child);
                        continue;
                    }
    
                    /**
                     * case 3.3 兄弟节点的左节点是红色,右节点是黑色
                     */
                    if ((other.left!=null && isRed(other.left)) && (other.right!=null && isBlack(other.right)) ) {
          
          
                        setBlack(other.left);
                        setRed(other);
                        rightRotate(other);
                        child = other;
                        parent = parentOf(other);
                        continue;
                    }
    
                    /**
                     * case 3.4:兄弟节点的左节点可以是任意颜色,右节点必须是红色
                     */
                    if (other.right != null && isRed(other.right)) {
          
          
                        setColor(other,colorOf(parentOf(child)));
                        setBlack(parentOf(child));
                        setBlack(other.right);
                        leftRotate(parentOf(child));
                        child = parentOf(parentOf(child));
                        parent = parentOf(child);
                        continue;
                    }
    
                }
                /** 当前节点是其父节点的右孩子 */
                // todo
                else {
          
          
    
                }
    
    
            }
    
        }
    
    }
    

猜你喜欢

转载自blog.csdn.net/Markland_l/article/details/114297983