Exploring
首页
  • Java

    • 面向对象的思想OOP
    • 浅谈Java反射原理
    • endorsed覆盖JDK中的类
  • 认证与授权

    • LDAP概念和原理介绍
    • OAuth2介绍
  • Impala

    • Impala 介绍
  • MySQL

    • 关于MySQL的一些面试题
    • 解决MySQL不到中文数据
    • 数据库之事务与实现原理
  • Oracle

    • oracle的表空间,用户管理,表操作,函数
    • oracle的查询、视图、索引
    • plsql简单入门
  • Redis

    • 数据类型详解
    • 跳越表
    • 数据持久化的两种方式
  • 共识算法

    • gossip
  • RPC

    • GRPC初识与快速入门
    • ProtocolBuffer基本语法
  • RabbitMQ

    • RabbitMQ入门程序之HelloWorld
    • RabbitMQ之工作模式
  • Zookeeper

    • Zookeeper一文入门
  • Docker

    • Docker入门初体验
  • Maven

    • 把自己的包到Maven中央仓库
    • Maven之自定义插件
  • Nginx

    • nginx的安装
    • nginx的配置文件
    • nignx 的变量
  • Tomcat

    • Servlet3通过SPI进行注册组件
  • Vagrant

    • vagrant 初始化
    • vagrant 常用配置
    • vagrant 自己制作 box
  • Linux

    • 启动方式 Systemd
    • 后台服务
    • 防火墙与 Iptables
  • 设计模式

    • 设计模式-代理
    • 设计模式-单例模式
    • 设计模式-迭代器
  • 分布式

    • CAP 理论
  • 数据结构

    • 数据结构之堆Heap
    • 数据结构之哈希表
    • 数据结构之队列
  • 计算机网络

    • HTTP与HTTPS详解
    • 浅谈DNS协议
    • ISP中的网络层
  • 算法

    • 常用查找算法及Java实现
    • 常用排序算法及Java实现
    • 迪杰斯特拉算法
  • 操作系统

    • 操作系统之进程调度算法
    • 操作系统之进程通讯IPC
    • 操作系统之内存管理
  • 抓包

    • 生成安卓系统证书
  • 加解密

    • 常见加密算法
    • 公开秘钥基础知识
    • RSA 解析
  • Windows

    • scoop 包管理
    • windows-terminal 配置
    • 增强 PowerShell
归档
Github (opens new window)
首页
  • Java

    • 面向对象的思想OOP
    • 浅谈Java反射原理
    • endorsed覆盖JDK中的类
  • 认证与授权

    • LDAP概念和原理介绍
    • OAuth2介绍
  • Impala

    • Impala 介绍
  • MySQL

    • 关于MySQL的一些面试题
    • 解决MySQL不到中文数据
    • 数据库之事务与实现原理
  • Oracle

    • oracle的表空间,用户管理,表操作,函数
    • oracle的查询、视图、索引
    • plsql简单入门
  • Redis

    • 数据类型详解
    • 跳越表
    • 数据持久化的两种方式
  • 共识算法

    • gossip
  • RPC

    • GRPC初识与快速入门
    • ProtocolBuffer基本语法
  • RabbitMQ

    • RabbitMQ入门程序之HelloWorld
    • RabbitMQ之工作模式
  • Zookeeper

    • Zookeeper一文入门
  • Docker

    • Docker入门初体验
  • Maven

    • 把自己的包到Maven中央仓库
    • Maven之自定义插件
  • Nginx

    • nginx的安装
    • nginx的配置文件
    • nignx 的变量
  • Tomcat

    • Servlet3通过SPI进行注册组件
  • Vagrant

    • vagrant 初始化
    • vagrant 常用配置
    • vagrant 自己制作 box
  • Linux

    • 启动方式 Systemd
    • 后台服务
    • 防火墙与 Iptables
  • 设计模式

    • 设计模式-代理
    • 设计模式-单例模式
    • 设计模式-迭代器
  • 分布式

    • CAP 理论
  • 数据结构

    • 数据结构之堆Heap
    • 数据结构之哈希表
    • 数据结构之队列
  • 计算机网络

    • HTTP与HTTPS详解
    • 浅谈DNS协议
    • ISP中的网络层
  • 算法

    • 常用查找算法及Java实现
    • 常用排序算法及Java实现
    • 迪杰斯特拉算法
  • 操作系统

    • 操作系统之进程调度算法
    • 操作系统之进程通讯IPC
    • 操作系统之内存管理
  • 抓包

    • 生成安卓系统证书
  • 加解密

    • 常见加密算法
    • 公开秘钥基础知识
    • RSA 解析
  • Windows

    • scoop 包管理
    • windows-terminal 配置
    • 增强 PowerShell
归档
Github (opens new window)
  • Java

    • 基础

      • 面向对象的思想OOP
      • 浅谈Java反射原理
      • endorsed覆盖JDK中的类
      • Java8新特性之函数式接口
      • Java集合之HashMap与ConcurrentHashMap
      • Java语法级常见面试题
      • Java中的四种引用类型详解
      • Java中的摘要算法MessageDigest
      • Java中注解Annotation概念及原理
      • Java中final关键词详解
      • jdk源码分析-TreeMap红黑树插入删除过程
        • 一、红-黑树的性质
        • 二、平衡化的旋转
        • 三、插入过程
    • 并发与多线程

    • 日志系统

    • 单元测试

    • JVM

    • Spring

    • SpringBoot

    • 一些工具

  • 语言
  • Java
  • 基础
unclezs
2019-06-17
0
目录

jdk源码分析-TreeMap红黑树插入删除过程

# 一、红-黑树的性质

# 1.简述

jdk中的TreeMap是由红黑树实现的,所以本文记录下我分析的红黑树 红黑树实际是实现二叉排序树的实现自平衡的算法之一,所以可以叫红黑树为高级二叉查找树。 如果不了解排序树请先学习排序树

# 2.性质

1.每个节点不是红色就是黑色的; 2.根节点总是黑色的; 3.如果节点是红色的,则它的子节点必须是黑色的(反之不一定); 4.从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。

# 二、平衡化的旋转

为了达到树的平衡我们需要对其进行旋转,下面说的是左右旋的基本概念

# 1.左旋

以5为节点进行左旋转 以E为节点进行左旋转示意图

# 2.右旋

以20为节点进行右旋转

以s为节点,右旋转示意图

# 三、插入过程

插入的时候为保证红黑树性质不被改变,插入后应该对其旋转操作,需要修复红黑树结构的情况为父节点为红色的时候

# 1.情况分析

我按照两种情况来分析需要旋转的情况 新插入的节点默认都为红色

# 1.1.父亲在左边

1.1.1 .叔叔为红色 这里不需要旋转,只需要换色即可,(父亲,叔叔)<--->(祖父),再将祖父当作根节点判断是否满足红黑树结构再进行操作

1.1.2 叔叔为黑色、我在左 这里只需要进行以父为节点右旋转,然后父亲->黑色,祖父->红色

1.1.3 叔叔为黑色、我在右边 这里要先对父节点做一次左旋,再以祖为节点右旋转

# 1.2.父亲在右边

1.2.1 叔叔为红色 和1.1.1一样 1.2.2 叔叔为黑色,我在左 这里需要以父为节点进行一次左旋,再以祖父为节点进行左旋转即可 1.2.1 叔叔为黑色,我在右 这里只需要以祖为节点左旋一次即可达到平衡

# 2.源码分析

回到java源码中对TreeMap中插入时修复红黑树的方法为fixAfterInsertion 源码:

private void fixAfterInsertion(Entry<K,V> x) {
      me.color=RED;
        //x为根节点时候不需要操作,x父亲为黑色时为正确红黑树,不需要修复
        while (me!=null&&me!=root&&me.parent.color==RED){
            //分两大种情况处理,父亲在左边或者右边时
            if(parentOf(me)==leftOf(parentOf(parentOf(me)))){//父亲在左边的时候
                Node<E> uncle = rightOf(parentOf(parentOf(me)));//获取叔叔(在右)
                if(colorOf(uncle)==BLACK){//叔叔为黑色
                    //此时父左,叔右,若我为左则以祖父为根R旋转,若我在右边则以我为根进行LR转
                    if(rightOf(parentOf(me))==me){//我在右边
                        me=parentOf(me);
                        leftRotate(me);
                    }
                    setColor(parentOf(me),BLACK);
                    setColor(parentOf(parentOf(me)),RED);
                    rightRotate(parentOf(parentOf(me)));
                }else {//叔叔为红色,交换颜色(父亲,叔叔)<->(祖父),再将祖父接着前操作
                    setColor(parentOf(uncle),RED);//祖父红色
                    setColor(parentOf(me),BLACK);//父亲黑色
                    setColor(uncle,BLACK);//叔叔黑色
                    me=parentOf(uncle);//祖父为节点接着修复
                }
            }
            else {//父亲在右边的时候
                Node<E> uncle = leftOf(parentOf(parentOf(me)));//获取叔叔(在左)
                if(colorOf(uncle)==BLACK){//叔叔为黑色
                    //此时父右,叔左,若我为左则以我为根RL旋转,若我在右边则以祖父为根进行L转
                    if(leftOf(parentOf(me))==me){//我在左边
                        me=parentOf(me);
                        rightRotate(me);
                    }
                    setColor(parentOf(me),BLACK);
                    setColor(parentOf(parentOf(me)),RED);
                    leftRotate(parentOf(parentOf(me)));
                }else {//叔叔为红色,交换颜色(父亲,叔叔)<->(祖父),再将祖父接着前操作
                    setColor(parentOf(uncle),RED);//祖父红色
                    setColor(parentOf(me),BLACK);//父亲黑色
                    setColor(uncle,BLACK);//叔叔黑色
                    me=parentOf(uncle);//祖父为节点接着修复
                }
            }
        }
        root.color=BLACK;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
在 GitHub 编辑此页 (opens new window)
上次更新: 2024/02/25, 12:11:11
Java中final关键词详解
Java并发之Unsafe类

← Java中final关键词详解 Java并发之Unsafe类→

Theme by Vdoing | Copyright © 2018-2024 unclezs
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式