1、简介

R-B Tree,全称Red-Black Tree,又称为“红黑树”,为一种自平衡二叉查找树(特殊的平衡二叉树,都是在插入和删除操作时通过特定操作保持二叉树的平衡,从而获得较高的查找性能)。红黑树的每个节点上都有表示存储位的颜色,可以是红色(Red)或黑色(Black)。

红黑树特性:

  • (1)每个节点要么是黑色,要么是红色。
  • (2)根结点必须是黑色。
  • (3)每个叶子结点是黑色(叶结点即指树尾端NIL指针或NULL结点)。
  • (4)不能有连续的两个红色结点。
  • (5)对于任意结点而言,其到叶结点树尾端NIL指针的每条路径都包括相同数目的黑结点。

正是红黑树的这5条性质,使得一颗n个结点的红黑树保持了Log n的高度,从而解释了红黑树的查找、插入、删除的时间复杂度最坏为O(Log n)这一结论成立的原因。

红黑树示意图一:

红黑树示意图二:

特性4表明:红色结点的父、左子、右子只能是黑色结点,红色和红色不能连接在一起;而黑色无论红色还是黑色都可以连在一起。(红色暴脾气互不相融,黑色和蔼可亲谁来都行)。

特性5表明:随便选一个结点,不论怎么走,走到最后叶子结点时,其经过的黑色结点数量都是相等的(所谓完全黑平衡)。

特性4、5共同决定了:最长路径的节点数量不会超过最短路径的两倍。因为黑色节点数量要一样,红色不能连着来,从而路径全黑时最短,红黑交替时最长。例如:四个黑色结点,最短:黑-黑-黑-黑(4),最长:黑-红-黑-红-黑-红-黑(7)。因为路径长度(高度)有了一定限制,所以称红黑树是有一定平衡性的,不会出现极端倾斜的情况。

2、红黑树应用

主要用来存储有序数据,时间复杂都为O(log n),效率非常高。如Java集合中的TreeMap、TreeSet、ConcurrentHashMap,C++中Set、map,以及Linux虚拟内存的管理都是用红黑树去实现的。

3、树的旋转

红黑树的基本操作是添加和删除。对红黑树进行添加和删除操作之后,红黑树会发生变化,此时可能不满足红黑树的5条特性。所以需要通过旋转来使这棵树重新成为红黑树。旋转操作包括:左旋和右旋两种操作。

仔细观察左旋与右旋的示意图,可以清晰的发现这两个操作是对称的。无论是左旋还是右旋,被旋转的树在旋转前是二叉查找树,且在旋转之后仍然是一棵二叉查找树。

旋转后,原来“左小右大”的特点不会受到影响。影响的是左右子树的高度,右旋左子树高度-1,右子树高度+1;左旋右子树-1,左子树+1。

比如某棵树的左子树高度已经达到3,而右子树只有1,只要右旋一下,左右子树高度都将调整为2.整个树看来,高度就相当于降低了1(3->2),这样就是高度"平衡"。

注意b:

右旋前,b是挂在Y的右子,而右旋后,挂到了X的左子了;
左旋前,b是挂在X的左子,而左旋后,挂到了Y的右子了;

4、树的插入

开始之前,先约定名称:

红黑树属于二叉搜索树,插入动作也与二叉搜索树一致,只不过红黑树在插入之后,多了平衡动作(旋转与涂色)。

新插入的节点均为红色节点,因为红色不会影响路径上黑色节点的数量,保持性质4。如果父节点为黑色,就直接结束了;如果父节点为红色,则需要另外处理了。

以新插入的节点为当前平衡节点N,插入平衡大体上分为以下情形:

用例:插入10,20,15,30,5,8。步骤说明:

  • N为根:涂黑完事;
  • 父黑:啥事不用管;
  • 父红叔红:父/叔涂黑,祖父涂红,然后把祖父当成新的平衡节点递归处理(我们下面平衡了,让他老人家和上面沟通吧);
  • 父红叔黑:父节点和新插入节点同一边的话,扭一下就完事了(同左右旋,同右左旋,顺便涂色);不在同一边的话,先扭到同一边吧。

5)树的删除

情况分析:

现在我们有一颗红黑树。

删除50

删除70,即黑色叶子节点,进行平衡:

删除60:

删除10:

删除20

R-B Tree的更多相关文章

  1. SPOJ 375 Query on a tree 树链剖分模板

    第一次写树剖~ #include<iostream> #include<cstring> #include<cstdio> #define L(u) u<&l ...

  2. tree命令的使用

    有些工作在linux下完成就是比在windows下完成高效! windows和linux都有tree命令,主要功能是创建文件列表,将所有文件以树的形式列出来 windows下的tree比较垃圾,只有两 ...

  3. 【BZOJ-4353】Play with tree 树链剖分

    4353: Play with tree Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 31  Solved: 19[Submit][Status][ ...

  4. 【BZOJ-2648&2716】SJY摆棋子&天使玩偶 KD Tree

    2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2459  Solved: 834[Submit][Status][Discu ...

  5. Educational Codeforces Round 6 E. New Year Tree dfs+线段树

    题目链接:http://codeforces.com/contest/620/problem/E E. New Year Tree time limit per test 3 seconds memo ...

  6. poj 3321 Apple Tree dfs序+线段树

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K       Description There is an apple tree outsid ...

  7. 泛函编程(8)-数据结构-Tree

    上节介绍了泛函数据结构List及相关的泛函编程函数设计使用,还附带了少许多态类型(Polymorphic Type)及变形(Type Variance)的介绍.有关Polymorphism的详细介绍会 ...

  8. SPOJ QTREE Query on a tree --树链剖分

    题意:给一棵树,每次更新某条边或者查询u->v路径上的边权最大值. 解法:做过上一题,这题就没太大问题了,以终点的标号作为边的标号,因为dfs只能给点分配位置,而一棵树每条树边的终点只有一个. ...

  9. 2014 Super Training #9 F A Simple Tree Problem --DFS+线段树

    原题: ZOJ 3686 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3686 这题本来是一个比较水的线段树,结果一个ma ...

  10. UPC 2224 Boring Counting (离线线段树,统计区间[l,r]之间大小在[A,B]中的数的个数)

    题目链接:http://acm.upc.edu.cn/problem.php?id=2224 题意:给出n个数pi,和m个查询,每个查询给出l,r,a,b,让你求在区间l~r之间的pi的个数(A< ...

随机推荐

  1. Once Again...

    Once Again... 题目链接 题意 给n个数,然后T次循环后组成一个新的数列,求这个数列的最长不递减子序列. 思路 因为最多就100个元素,所以当m<=100的时候直接暴力求最长不递减子 ...

  2. Spurious Local Minima are Common in Two-Layer ReLU Neural Networks

    目录 引 主要内容 定理1 推论1 引理1 引理2 Safran I, Shamir O. Spurious Local Minima are Common in Two-Layer ReLU Neu ...

  3. KISS原则

    Keep It Simple, Stupid 1. 模块性原则:写简单的,通过干净的接口可被连接的部件:2. 清楚原则:清楚要比小聪明好.3. 合并原则:设计能被其它程序连接的程序.4. 分离原则:从 ...

  4. capstoneCS5213|HDMI转VGA带DAV模拟音频输出转换器|CS5213方案

    capstone CS5213是一款HDMI到VGA转换器结合了HDMI输入接口和模拟RGB DAC输出且带支持片上音频数模转换器.CS5213芯片设计简单,整体芯片尺寸精悍,外围电路集成优化度较高, ...

  5. Java初学者作业——编写JAVA程序,计算跳水运动员本次动作的最终得分。

    返回本章节 返回作业目录 需求说明: 编写JAVA程序,计算跳水运动员本次动作的最终得分. 规则如下: 在跳水比赛中,共有六位裁判对运动员所完成的动作进行评分,每位裁判的评分在0-10之间,运动员最终 ...

  6. ORA-09925:Unable to create audit trail file 数据库启动失败

    问题描述:生产库停机加内存和CPU,重启完服务器,启动数据库报错. ORA-09925: Unable to create audit trail file Linux-x86_64 Error 2: ...

  7. [学习笔记] SpringBoot 之 Helloworld

    创建项目 IDEA / File / New / Project / Spring Initalizr / Next Group: com.wu 公司官网域名反写 Artifact: hellowor ...

  8. How to run a batch file each time the computer loads Windows

    https://www.computerhope.com/issues/ch000322.htm#:~:text=Press Start%2C type Run%2C and press Enter. ...

  9. 360浏览器兼容模式下jsp页面访问不到js文件

    360浏览器兼容模式下jsp页面访问不到js文件 查看自己js中的语法问题,不要用ES6的语法,编译不了故找不到js文件 const var of 码出高效 java 比较 所有整型包装类对象之间值的 ...

  10. 使用Spring容器动态注册和获取Bean

    有时候需要在运行时动态注册Bean到Spring容器,并根据名称获取注册的Bean.比如我们自己的SAAS架构的系统需要调用ThingsBoard API和Thingsboard交互,就可以通过Thi ...