数据结构算法之红黑树

红黑树

红黑树的基本性质和复杂度分析

1.每个节点或者是红色的,或者是黑色的

2.根节点是黑色的

3.每一个叶子节点(最后的空节点)是黑色的

4.如果一个节点是红色的,那么他的孩子节点都是黑色的

5.从任意一个节点到叶子节点,经过的黑色节点是一样的

package com.ffyc.lesson.lesson11;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;

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

    private class Node<T> {
        T val;
        Node left;
        Node right;
        //结点的颜色

        boolean isRed;


        int count;//统计次数
        Node(T val) {
            this.val = val;
            this.left = this.right = null;
            this.isRed = true;//新建的结点是红色
            this.count=1;
        }
    }

    //红黑树的特性
    private Node<T> root;//根结点

    private int size;

    //判断是否为空
    public boolean isEmpty() {
        return this.size == 0;
    }

    //获取结点的个数
    public int getSize() {
        return this.size;
    }

    //获取结点颜色的公共方法
    public boolean getNodeColor(Node node){
        if (node==null){
            return  false;
        }
        return node.isRed;
    }

    public void add(T val) {
        this.root = add(this.root, val);

        //更新根结点的颜色
        this.root.isRed = false;
    }

    //向以node为根的红黑树中添加结点v
    private Node<T> add(Node<T> node, T v) {
        //递归到底的情况
        if (node == null) {
            this.size++;
            return new Node(v);
        }
        Node result=null;
        if (node.val.compareTo(v) > 0) {
            node.left = add(node.left, v);
        }else if(node.val.compareTo(v)<0){
            node.right=add(node.right,v);
        }else{
            node.count++;
        }
        result=node;
        //对result进行处理
        //左旋
        if (getNodeColor(result.right)&&!getNodeColor(result.left)){
            result=leftRoTate(result);
        }

        //右旋
        if (getNodeColor(result.left)&&getNodeColor(result.left.left)){
            result=rightRoTate(result);
        }
        //颜色翻转
        if (getNodeColor(result.left)&&getNodeColor(result.right)){
            flipColor(result);
        }
        return  result;
    }

    public  void levelTravel(){
        //1.使用队列
        Queue<Node>  queue=new LinkedList<>();
        //2.将根节点放入队列
        if (this.root==null){
            return;
        }
        queue.offer(this.root);
        //3.循环判断
        while (!queue.isEmpty()) {  //每次循环从左往右放入节点
            Node node = queue.poll();
            System.out.println("val:"+node.val+",color:"+(node.isRed?"Red":"Black")+",次数"+node.count);
            if (node.left != null) { //左节点放进去
                queue.offer(node.left);
            }
            if (node.right != null) {	//又节点放进去
                queue.offer(node.right);
            }
        }

    }


    //左旋转的代码
    public Node leftRoTate(Node node) {
        Node x = node.right;
        Node t2 = x.left;

        node.right=t2;
        x.left = node;
        //颜色更新
        x.isRed = node.isRed;
        //node可能是融合结点
        node.isRed = true;

        return x;
    }

    //颜色旋转
    public void flipColor(Node node) {
        node.left.isRed = false;
        node.right.isRed = false;
        //node可能是融合结点
        node.isRed = true;
    }


    //右旋转的代码
    public Node rightRoTate(Node node) {
        Node x = node.left;
        node.left = x.right;
        x.right = node;


        //颜色更新
        x.isRed = node.isRed;
        //node可能是融合结点
        node.isRed = true;

        return x;
    }



    public static void main(String[] args) {
        RBTree<Integer>  rbTree=new RBTree<>();
        int[]  arr={1,3,5,54,13,12,11,5,24,6,23,6,8,6};
        Arrays.stream(arr).forEach(rbTree::add);
        System.out.println(rbTree.getSize());
        rbTree.levelTravel();
    }
}

查询操作远多于插入和删除操作时,AVL树很好用

红黑树是用非严格的平衡来换取增删节点时的旋转次数来降低开销

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个想挣钱的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值