红黑树插入操作步骤分解

23树是具有绝对平衡的二叉树,即平衡因子是0(AVL树平衡因子控制在1),而红黑树模仿了23树的特征,但是不是真正意义上的平衡树。
画一下23树和红黑树比较一下就清楚了
在这里插入图片描述
如上图所示,左边的是23树,右边的是红黑树。

红黑树的特点是左倾斜,即右不能有红色节点,如果有红色节点 要进行如下操作。

1.左旋转,左节点是黑,右结点是红
在这里插入图片描述
旋转完成后,交换两个节点的颜色。
2.如果是这种情况,直接改变两个子节点的颜色为黑色,根节点变红,整个过程相当于颜色的翻转
在这里插入图片描述
3.还有这种左子树连续两个都是红色的,此时进行右旋转,然后交换颜色,再进行颜色翻转
在这里插入图片描述

完整代码如下

package rbtree;

public class Test1 {
    static final boolean RED=true;
    static final boolean BLACK=false;
   static class Node{

        int data;
        Node left;
        Node right;
        boolean color;
        public Node(int data){
            this.data=data;
            left=null;
            right=null;
            color=RED;
        }

    }
   static class BST{
        Node root;

        //root结点
        public BST(Node root){
                this.root=root;
        }

       // 判断节点node的颜色
       private boolean isRed(Node node){
           if(node == null)
               return BLACK;
           return node.color;
       }

       //   node                     x
       //  /   \     左旋转         /  \
       // T1   x   --------->   node   T3
       //     / \              /   \
       //    T2 T3            T1   T2
       private Node leftRotate(Node node){

           Node x = node.right;

           // 左旋转
           node.right = x.left;
           x.left = node;

           x.color = node.color;
           node.color = RED;

           return x;
       }

       //     node                   x
       //    /   \     右旋转       /  \
       //   x    T2   ------->   y   node
       //  / \                       /  \
       // y  T1                     T1  T2
       private Node rightRotate(Node node){

           Node x = node.left;

           // 右旋转
           node.left = x.right;
           x.right = node;

           x.color = node.color;
           node.color = RED;

           return x;
       }


       //翻转
       public void flipColor(Node node){
            node.left.color=BLACK;
            node.right.color=BLACK;
            node.color=RED;
       }
        //插入操作
        private Node insert(Node node,int data){
             if (null==node){
                 return new Node(data);
             }

             if (node.data>data){
               node.left=insert(node.left,data);
             }else if (node.data<data){
                 node.right=insert(node.right,data);
             }
            if (isRed(node.right) && !isRed(node.left))
                node = leftRotate(node);

            if (isRed(node.left) && isRed(node.left.left))
                node = rightRotate(node);

            if (isRed(node.left) && isRed(node.right))
                flipColor(node);
             return node;
        }

       //插入操作
       public void insert(int data){
            insert(root,data);
            root.color=BLACK;
       }
    }

    public static void main(String[] args) {
        BST bst = new BST(new Node(1));
        bst.insert(2);

        bst.insert(0);
        bst.insert(4);
        bst.insert(3);
        bst.insert(60);
       preorderTraversal(bst);
       delete(bst,4);
       preorderTraversal(bst);
//       find(bst,4);

    }
    public static  void preorderTraversal(BST bst){
         preorderTraversal(bst.root);
    }
    private static  void preorderTraversal(Node node){
            if (node==null){
                return;
            }
            //先序遍历
            System.out.println(node.data);
            preorderTraversal(node.left);
            preorderTraversal(node.right);
    }

    //查找二叉树指定的数,根据二叉树左子节点小于父节点,和右子节点大于父节点的特性来递归查找
    private static  Node find(Node node,int data){
        if (node.data==data){
            return node;
        }
        if (node.data>data){
           return find(node.left,data);
        }else{
            return find(node.right,data);
        }
    }

    //查找二叉树指定的数,根据二叉树左子节点小于父节点,和右子节点大于父节点的特性来递归查找
    public static  void find(BST bst,int data){
        Node node = find(bst.root, data);
//        System.out.println(node.data);
    }

    public static void delete(BST bst,int data){
            delete(bst.root,data);
    }
    //删除节点
    private static void delete(Node node,int data){
        Node n=node ;
        Node fatherN=null;
        while (n!=null&&n.data!=data){
            fatherN=n;
            if (n.data>data){
               n=n.left;
            }else{
                n=n.right;
            }
        }
        if (null==n){
            return;
        }
        //第一种情况,两边节点都有
        if (n.left!=null&&n.right!=null){
            Node minNumber=n.right;//找出子节点
            Node minNumberFather=n;//找出父节点

            while (minNumber.left!=null){
                minNumberFather=minNumber;
                minNumber=minNumber.left;
            }
//            findMinNumber(minNumberFather,minNumber);
            n.data=minNumber.data;//赋值
            //下面做统一的判断
            n=minNumber;
            fatherN=minNumberFather;
        }

        Node chirld;

        if (n.left!=null){
            chirld=n.left;
            return;
        }else if (n.right!=null){
            chirld=n.right;
        }else {
            chirld=null;
        }

        if (fatherN.left==n){
            fatherN.left=chirld;
        }else if (fatherN.right==n){
            fatherN.right=chirld;
        }else{
            node=chirld;
        }

    }


}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值