一、红黑树

特性:1.每个节点是黑色或者红色的

2.根节点是黑色的

3.每个叶节点(NIL)是黑色的

4.不能有相连的红色节点

5.对每个节点,从该节点到其所有叶节点的路径上,均包含相同数量的黑色节点。

红黑树插入:

详细插入:

接上

插入总结:

1.插入红节点(如果黑节点就会出现链表情况,不违反红黑树的特性)

2.待插入节点z与父节点p冲突。

2.1 叔节点u为红色。则需将爷爷节点pp变红,p和u变红。且将pp标记为新的z

2.2 u为黑色。则需要旋转(以z的父节点为轴旋转)。并将父节点p标记为新的z

3.一次以p的旋转必然伴随着一次以pp的旋转。(当z与p与pp同一条线即同一侧,则直接以pp旋转一次即可)

4.循环的修复红黑树的特性,目标是修复到z.p.color为黑色的时候退出循环

红黑树删除(比较复杂,引入算法导论中伪代码与图形):

1.位置替换伪代码:

/***    只是处理了u.p的指针指向。在外部还需手动处理v的子类指针**/
RB-TRANSPLANT(T, u, v) {if(u.p == T.nil) {T.root = v}else if (u == u.p.left) {u.p.left = v}else u.p.right = vv.p = u.p
}

   2. 删除伪代码:

RB-DELETE(T, z) {y = zy-original-color = y.colorif (z.left == T.nil) {x = z.rightRB-TRANSPLANT(T, z, z.right)} else if (z.right == T.nil) {x = z.leftRB-TRANSPLANT(T, z, z.left);} else {y = TREE-MINIMUM(z.right) // z的后继节点y-original-color = y.colorx = y.rightif (y.p == z) { // y为z的右子节点,且是后继节点x.p = y// z被y替换时。y的右节点不需要处理。左节点需要自处理}else {RB-TRANSPLANT(T, y, y.right) // 为z被y替换处理,子节点需要自处理。左右节点都需要处理y.right = z.right y.right.p = y} RB-TRANSPLANT(T, z, y)// z被y替换之后,子节点的自处理。此处只需要处理左节点y.left = z.lefty.left.p = yy.color = z.color // 将y置为z的color.最终影响树性质的,决定权在y的原始颜色,y-original-color}// z只存在一个子节点的时候。y==z。y == z.color.影响树的性质,依然由y-original-color控制if (y-original-color == BLACK) {RB-DELETE-FIXUP(T, x)}}

3.删除-红黑树性质修复伪代码:

y的原始颜色y-original-color==RED时。

1.黑高不会变换。

2.y一定不是根节点,所以根节点依然是黑色

3.y只存在一个子节点的时候,y == z 。z被y的唯一子节点代替,无任何改变红黑树性质的可能。

4.y存在两个子节点,且y为z的右子节点时,即y也是z的后继节点。后继节点必然为其右子树中最小的,且y不存在左节点了。y为红色则y.right一定为黑色。y.right替换掉y之后红黑树性质也不可能冲突。

y的原始颜色y-original-color==BLACK时。

1.y为根节点,则其子节点替换,根节点就变红色,则违反了性质2。

2.删除之后,x与x.p(删除之前y.p)都为红色。则违反了性质4

3.将包含y的任一子树的黑节点个数都少一。因此y的任何祖先都补满足性质5。针对这一情况,算法导论中的处理方式为:将y的黑色下方到x,x为红色(自身黑属性+下方红),黑色(自身黑属性+下方黑色),x多出来的黑色并不是体现在x的color属性上,而是针对的x节点。包含x的子树中,x共享了一重黑色,或则两重黑色,从而保证了性质5。但是x却违反了性质1。

RB-DELETE-FIXUP:

RB-DELETE-FIXUP(T, x) {while (x != T.root && x.color == BLACK) {// x作为左节点if (x == x.p.left) {// x的兄弟节点ww = x.p.right// 情况1:x的兄弟结点w为红色,x.p.color必然为黑色。// 为保证红黑树的特性,可以将x.p与w的颜色改变// 接着以x.p为轴左转,并不会影响特性。就变成情况2,3,4if (w.color == RED) {w.color = BLACKx.p.color = REDLEFT-ROTATE(T, x.p)w = x.p.right}// 经过情况1的过滤:2,3,4的w必然是为黑色的// 情况2:w黑色,w的两个子节点都是黑色的// 将x上移至x.p,则w子树就会随着x多了一层黑,则需将w变红if (w.left.color == BLACK && w.right.color == BLACK) {x = x.p // 如果是情况1过来的,则此时x为红黑色,x.color = RED。所以得退出循环,并将x.color = BLACKw.color = RED} // 情况3:w黑色, w左孩子红色,w的有孩子为黑色// 交换w.left和w的颜色,并以w向右旋转。则特性不会变。并将w置为x.p.right.// 情况3就变为情况4了else if (w.right.color == BLACK) {w.left.color = BLACKw.color = REDRIGHT-ROTATE(T, w)w = x.p.right}// 情况4:w黑色,w的右孩子是红色的// 将x.p、w、w.right的颜色变换,并以x.p为轴向左旋转,即可保证特性,也可顺带去掉x的多一层黑色。else {// w与x.p的颜色交换// 以x.p为轴旋转,则w子树必然少一个黑,所以将w.right置黑。// 而x所在子树因转来个x.p的黑节点,则多一黑,刚好x的颜色多了黑直接去掉// x置为root 退出循环。w.color = x.p.color x.p.color = BLACK w.right.color = BLACKLEFT-ROTATE(T, x.p)x = T.root}}}x.color = BLACK
}

4.删除-图形示例:

总结:红黑树删除,需要找到后继节点y(可能为z的右节点,也有可能非右节点的后继)。

1.  红黑树增加维持红黑树的特性是看其叔叔,删除是看其兄弟节点控制x和w的移动变换,以及旋转和相关的变色。

2. 循环的修复红黑树特性,情况2由情况1过来,导致x.color=red只是作为x多了一层额外的黑色,从而退出循环。还有就是目的性的调整到x的兄弟节点为黑色,且w.right=red即情况4,很容易将原x的子树增加1曾黑色且将x置为root退出循环。

二、B树

一个B树结点通常和一个完整磁盘页一样大,并且磁盘页的大小限制了一个B树结点可以含有的孩子的个数。一个典型的磁盘的长度,可能为2^11~2^14字节。

度:每个结点包含的关键字个数有上界和下界。用一个被称为B树的最小度数degree的固定整数t>=2来表示这些界。

a.除了根结点以外的每个结点必须至少有t-1个关键字。因此除了根结点之外的每个内部结点至少有t个孩子。如果树非空,根结点至少有一个关键字。

b.每个结点至多可包含2t-1个关键字。因此一个内部结点至多有2t个孩子。当一个结点恰好有2t-1个关键字,则称该结点是满的full。

t =< 内部结点数 <= 2t

阶:对于一个m阶B树,根结点的子结点个数为1~m,非根结点的子关键字个数为[m/2]-1~m-1。子结点个数为[m/2]~m.因为当前节点满了之后,继续添加关键字。必然分裂成两半也就是[m/2]-1个关键字,[m/2]个子结点。

[m/ 2]=< 内部结点数 <= m

·综上:m = 2d。

1. B数的插入

伪代码就不贴上了

总结:插入是预分裂。确保到任何叶结点可以直接插入。

插入叶结点,未full(关键字数 = 2d - 1)直接插入。当叶子结点full则需要按中间值分裂。并上移中间关键字。插入的过程中如果发现,遍历的过程中,有full的结点,则提前分裂,分裂好之后再接着遍历插入。

2. B树的删除

总结:删除是预合并,或者预向兄弟结点借用。

1. 被删除节点x的关键字必须满足(t~2t-1).满足条件的叶结点直接删除。

2. x为内部结点,且满足至少t个关键字。则需找k的前驱prev或者后继suc。

ab.如果prev和suc至少有一个满足至少t个关键字,则找到k的前驱k1或者后继(递归下去)。使用k1代替k。

c.prev和suc都不满足至少一个关键字t,皆是t-1个下限关键字。则将k下移至prev且将suc合并至prev并将suc中的孩子指针移动到prev。

3. 从根节点遍历下移的过程中,遇到t-1个的关键字x。

a.找到x的相邻的两个兄弟结点,如果有满足至少t个关键字的b结点。则将b中的关键字上移至父节点(注意递归),并将父节点中的关键字下移至x。并将b中的孩子子指针移入x。

b.找不到满足条件的兄弟结点,则将父节点关键字下移,且将兄弟结点b合并到x。且

b的孩子指针移入x。

三.234树

234树为度数为2的B树。也可与红黑树相互转换.

红黑树、B树、234树相关推荐

  1. 为什么HashMap使用红黑树而不使用AVL树

    在Jdk1.8版本后,Java对HashMap做了改进,在链表长度大于8的时候,将后面的数据存在红黑树中,以加快检索速度. 那么很多人就有疑问为什么是使用红黑树而不是AVL树,AVL树是完全平衡二叉树 ...

  2. 遍历HashMap源码——红黑树原理、HashMap红黑树实现与反树型化(三)

    本章将是HashMap源码的最后一章,将介绍红黑树及其实现,HashMap的remove方法与反树型化.长文预警~~ 遍历HashMap源码--红黑树原理.HashMap红黑树实现与反树型化 什么是红 ...

  3. 面试题:为什么用红黑树不用普通的AVL树

    在Jdk1.8版本后,Java对HashMap做了改进,在链表长度大于8的时候,将后面的数据由链表改为了存在红黑树中,以加快检索速度. 有疑问为什么是使用红黑树而不是AVL树,AVL树是完全平衡二叉树 ...

  4. 2-3树------2-3-4树-----左倾红黑树

    2-3树: 2-节点:含有一个键和两条链接,左链接指向的2-3树中的键都小于该节点,右链接指向的2-3树中的键都大于该节点. 3-节点:含有两个键和三条链接,左链接指向的2-3树中的键都小于该节点,中 ...

  5. B树,B+树,红黑树应用场景AVL树,红黑树,B树,B+树,Trie树

    B B+运用在file system database这类持续存储结构,同样能保持lon(n)的插入与查询,也需要额外的平衡调节.像mysql的数据库定义是可以指定B+ 索引还是hash索引. C++ ...

  6. 为什么HashMap使用红黑树而不是AVL树或者B+树

    红黑树和AVL树都是最常用的平衡二叉搜索树. 但是,两者之间有些许不同: AVL树更加严格平衡,因此可以提供更快的査找效果.因此,对于查找密集型任务使用AVL树没毛病. 但是对于插入密集型任务,红黑树 ...

  7. 从2-3-4树谈到Red-Black Tree(红黑树)

    从2-3-4树谈到红黑树 译者:July. 出处:http://blog.csdn.net/v_JULY_v . 在上一篇文章--从B树.B+树.B*树谈到R 树里已提到2-3-4树,那么本文,咱们就 ...

  8. 通过2-3-4树理解红黑树

    前言 红黑树是数据结构中比较复杂的一种,最近与它交集颇多,于是花了一周的空闲时间跟它死磕,终于弄明白并实现了红黑树.写文总结一下,希望能给试图理解红黑树的同学一些灵感,也让我能记得更深刻. 在研究红黑 ...

  9. 树及树的算法(4) —— 红黑树

    红黑树是在1972年由德国科学家鲁道夫·贝尔发明的,他称之为"对称二叉B树",它现代的名字是在 Leo J. Guibas和 Robert Sedgewick 于1978年写的一篇 ...

  10. 美团实习面试:熟悉红黑树是吧?能不能写一下?

    点击关注公众号,Java干货及时送达 手写红黑树确实有点过分了,但我觉得写不出来也正常,只要理解就行 红黑树是数据结构中比较复杂的一种,最近与它交集颇多,于是花了一周的空闲时间跟它死磕,终于弄明白并实 ...

最新文章

  1. ASP .NET Core使用connection string连接MySQL/MariaDB,并设置UTF-8编码
  2. Oracle SCN
  3. 使用CGlib出现java.lang.NoClassDefFoundError: org/objectweb/asm/Type异常
  4. OPW-00001: Unable to open password-file
  5. Bigtable 论文翻译
  6. mysql结构优化_MySQL优化----数据库结构优化
  7. javaone_JavaOne 2012:观察与印象
  8. c语言中 字符串常量的界定符,c语言题库2
  9. Arduino笔记-对开关的基本认识
  10. 翻译文章第六章8-11
  11. 祝贺Terrylee博客园Post达到100篇
  12. ARM汇编开关终端cpsie/cpsid
  13. oracle unused 语法_Oracle教程之设置为unused 后如何恢复 ?
  14. 麦克纳姆轮全向移动机器人斜向直线运动分析
  15. localStorage的跨与实现方案
  16. OSSIM安装zabbix
  17. android x5webview截长图
  18. java 中文繁体转换简体
  19. 【日常】CCB网上银行“云宠物”喂食自动化脚本
  20. 会计信息质量可靠性的案例_浅谈会计信息可靠性(一)

热门文章

  1. 红米K40 Gaming刷入面具获取root
  2. SQL通配符——LIKE
  3. 华南师范大学陈卫东算法设计与分析研究生考试复习资料
  4. 关于数理统计学及其与概率论之间联系的一些理解
  5. HTML语言编写的树形导航栏代码
  6. win10+centos8双系统的安装
  7. 安卓代码怎么设置省电模式_安卓手机怎么设置省电模式
  8. c#中显示Excel控件使用说明
  9. 《Java多线程编程核心技术》(二)
  10. linux命令操作改变图片大小,如何在Linux命令行中优化和压缩JPEG或PNG图像