红黑树原理

一.简介
红黑树作为一种二叉搜索树的一种实现,红黑树的左右子树高度差可能大于 1。所以红黑树不是严格意义上的平衡二叉树(AVL),但红黑树是黑色节点完美平衡, 其平均统计性能要强于 AVL 。

红黑树是每个节点都带有颜色属性的二叉查找树,颜色为红色或黑色。
1.节点是红色或黑色。

2.根节点是黑色。

3.每个红色节点的两个子节点都是黑色。(红色节点的子节点必须是黑色节点)

4.从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

故红黑树是黑色平衡的树,左子树与右子树高度差不会超过2倍。红节点的父节点、子节点只能是黑节点

如果插入节点是黑色则所在路径将多出一个黑色节点,故新插入节点是红色节点(插入/删除红色节点不会改变所在路径黑色节点数量),通过旋转和调整节点颜色保证树的平衡

二.实现
红黑树增加/删除节点时需要保证子树黑节点平衡,有如下情况:

1.插入节点为树的根节点时,把根节点颜色修改为黑色

2.插入节点父节点是黑色节点,由于插入节点是红色节点,不会影响该子树黑色节点数量,故不用任何处理

3.插入节点父节点为红色且父节点的兄弟节点也为红色,父节点、父节点的兄弟节点修改为黑色,父节点的父节点修改为红色,再以父节点的父节点为插入节点递归处理

4.父节点为红色且父节点的兄弟节点为null或为黑节点
由于父节点是红色节点,故父节点的父节点为黑色节点

1)LL型
插入数据父节点的兄弟节点只会为null,如果不为null则父节点的兄弟节点子树与父节点将不是平衡的。

修改父节点为黑色节点,祖父节点修改为红色节点
对祖父节点右旋转,让父节点为子树根节点,由于子树黑节点数量没有发生变化,故旋转后黑节点数量和旋转前一样

2)LR型
父节点左旋转将变为LL型,按LL型处理

3)RR型
修改父节点为黑色,祖父节点修改为红色,对祖父节点左旋转,让父节点为子树根节点,旋转后和旋转前黑色节点数量没有改变,故事黑色节点平衡

4)RL型
父节点右旋转变为RR型,按RR型处理

示例说明:

插入数据:4,3,6,5,7,8,9,10,11

package com.vincent;

import java.util.*;

public class Main {
public static void main(String[] args) throws Exception {
RBTree tree = new RBTree<>();
for(Integer data : Arrays.asList(4,3,6,5,7,8,9,10,11)){
tree.add(data);
System.out.println(tree.getRoot());
}
System.out.println();
List list = tree.infixList();
System.out.println(list);

    tree.delete(list.get(0));

    list = tree.infixList();
    System.out.println(list);

    tree.delete(list.get(list.size()-1));

    list = tree.infixList();
    System.out.println(list);

    tree.delete(list.get(list.size()/2));

    list = tree.infixList();
    System.out.println(list);
}

}

//红黑树
class RBTree<T extends Comparable>{
private static final int RED = 0;
private static final int BLACK = 1;

static class Node<T extends Comparable<T>> {
    private T item;
    private int color = RED;
    private Node<T> left;
    private Node<T> right;
    private Node<T> parent;

    public Node(T item) {
        this.item = item;
    }

    public T getItem(){
        return item;
    }

    /**
     * 添加节点到当前节点树
     * @param node      添加的节点
     */
    public void add(Node<T> node){
        if(node.item.compareTo(this.item) <= 0){
            if(this.left == null){
                this.left = node;
                node.parent = this;
            }
       
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值