红黑树特性以及插入破坏平衡的情况以及修复方法以及java实现

红黑树特性

  1. 每个节点一定是黑色或红色
  2. 插入的节点一定是红色
  3. 从任意一个节点到任意一个根节点经过的黑色节点都相同
  4. 红色节点的子节点和父节点必是黑色节点
  5. 红黑树根节点一定是黑色

在这里插入图片描述

代码实现

package com.platform.idleplatform.a;

public class BlackRedTree {
    public static void main(String[] args) {
        Node node = new Node();
        node.setValue(1);
        node.setRed(false);
        BlackRedTree blackRedTree = new BlackRedTree(node);
        blackRedTree.insert(2);
        blackRedTree.insert(3);
        blackRedTree.insert(4);
        blackRedTree.insert(5);
        blackRedTree.insert(6);
        blackRedTree.insert(7);
        blackRedTree.insert(8);
        blackRedTree.insert(9);
        blackRedTree.insert(10);
        blackRedTree.print(blackRedTree.findRoot(node));
    }
    private Node root;

    public Node findRoot(Node node){
        Node p = node;
        while (true) {
            if (p.getParent() != null) {
                p = p.getParent();
            }else {
                return p;
            }
        }
    }
    public BlackRedTree(Node root){
        this.root =root;
    }
    public  void insert(Integer value){
        Node node = new Node();
        node.setRed(true);
        node.setValue(value);
        insert(node,value);
        fix(node);
    }

    public void print(Node node){
        if (node == null) {
            return;
        }
        System.out.println(node.getValue() + (node.getRed() ? "红" : "黑"));
        System.out.println(node.getValue().toString() + '左');
        print(node.getLeft());
        System.out.println(node.getValue().toString() + '右');
        print(node.getRight());
    }
    private void insert(Node node,Integer value){
        Node p = findRoot(this.root);
        while (true){
            if (node.getValue() > p.getValue()){
                if (p.getRight() != null){
                    p = p.getRight();
                }else {
                    p.setRight(node);
                    node.setParent(p);
                    break;
                }
            }else {
                if (p.getLeft() != null){
                    p = p.getLeft();
                }else {
                    p.setLeft(node);
                    node.setParent(p);
                    break;
                }
            }
        }
    }
    //进行左旋
    private void leftRota(Node node){
        Node parent = node.getParent();
        Node right = node.getRight();
        if (right.getLeft() != null) {
            node.setRight(right.getLeft());
        }
        if (parent != null){
            parent.setRight(right);
        }
        right.setParent(node.getParent());
        node.setParent(node.getRight());
        node.setRight(right.getLeft());
        right.setLeft(node);
    }
    //进行右旋
    private void righttRota(Node node){
        Node parent = node.getParent();
        Node left = node.getLeft();
        if (left.getLeft() != null) {
            node.setRight(left.getLeft());
        }
        if (parent != null) {
            parent.setLeft(left);
        }
        left.setParent(node.getParent());
        node.setParent(node.getLeft());
        node.setLeft(left.getRight());
        left.setRight(node);
    }
    //进行修复
    private void fix(Node node) {
        Node parent = node.getParent();
        if (parent != null) {
            //父节点为为黑色节点不用修复
            if (!parent.getRed()) {
                return;
            }
            Node graparent = parent.getParent();
            //父节点左节点
            if (parent.getLeft() == node) {
                //为爷爷节点左节点
                if (graparent.getLeft() == parent) {
                    //左左双红
                    if (!graparent.getRight().getRed() || graparent.getRight() == null) {
                        //叔叔节点为黑或为空 为父节点左节点 爷爷节点左节点 把父节点变为黑色 把爷爷节点变为红色,然后对爷爷节点右旋 对应情景4.2.1
                        parent.setRed(false);
                        graparent.setRed(true);
                        righttRota(graparent);
                    } else {
                        //叔叔节点为红色,把叔叔节点变为黑色 父节点变为黑色 把爷爷节点变为红色,以爷爷节点为当前节点,进行下一轮修复 对应情景4.1
                        graparent.getRight().setRed(false);
                        parent.setRed(false);
                        graparent.setRed(true);
                        fix(graparent);
                    }

                } else {
                    //为爷爷节点右节点 父节点的左节点 且叔叔节点为空或黑色 先对父节点右旋 然后以父节点为当前节点进行下一轮跳转 对应情景4.3.2
                    if (graparent.getLeft() == null || !graparent.getLeft().getRed()) {
                        righttRota(parent);
                        fix(parent);
                    } else {
                        //叔叔节点为红色,把叔叔节点变为黑色 父节点变为黑色 把爷爷节点变为红色,以爷爷节点为当前节点,进行下一轮修复 对应情景4.1
                        graparent.getLeft().setRed(false);
                        parent.setRed(false);
                        graparent.setRed(true);
                        fix(graparent);
                    }
                }
            } else {
                //叔叔节点为黑或为空 为父节点右节点 爷爷节点左节点 先对父节点进行左旋,然后以父节点为当前节点继续调整 对应情景4.2.2
                if (graparent.getLeft() == parent) {
                    if (!graparent.getLeft().getRed() || graparent.getLeft() == null) {
                        leftRota(parent);
                        fix(parent);
                    } else {
                        //叔叔节点为红色,把叔叔节点变为黑色 父节点变为黑色 把爷爷节点变为红色,以爷爷节点为当前节点,进行下一轮修复 对应情景4.1
                        graparent.getRight().setRed(false);
                        parent.setRed(false);
                        graparent.setRed(true);
                        fix(graparent);
                    }

                } else {
                    //叔叔节点为黑或为空 为父节点右节点 爷爷节点右节点 把父节点变为黑色 把爷爷节点变为红色,然后对爷爷节点左旋 对应情景4.3.1
                    if (graparent.getLeft() == null || !graparent.getLeft().getRed()) {
                        parent.setRed(false);
                        graparent.setRed(true);
                        leftRota(graparent);
                    } else {
                        //叔叔节点为红色,把叔叔节点变为黑色 父节点变为黑色 把爷爷节点变为红色,以爷爷节点为当前节点,进行下一轮修复 对应情景4.1
                        graparent.getLeft().setRed(false);
                        parent.setRed(false);
                        graparent.setRed(true);
                        fix(graparent);
                    }
                }
            }
        }
        findRoot(node).setRed(false);
    }
}

//红黑树节点
class Node{

    //是否为红色节点 0为红色节点 1为黑色节点
    private Boolean isRed;
    //存放左节点
    private Node left;
    //存放右节点
    private Node right;
    //存放值
    private Integer value;
    //存放父节点
    private Node parent;

    public Boolean getRed() {
        return isRed;
    }

    public void setRed(Boolean red) {
        isRed = red;
    }

    public Node getLeft() {
        return left;
    }

    public void setLeft(Node left) {
        this.left = left;
    }

    public Node getRight() {
        return right;
    }

    public void setRight(Node right) {
        this.right = right;
    }

    public Integer getValue() {
        return value;
    }

    public void setValue(Integer value) {
        this.value = value;
    }

    public Node getParent() {
        return parent;
    }

    public void setParent(Node parent) {
        this.parent = parent;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值