红黑树算法介绍

Posted yll1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了红黑树算法介绍相关的知识,希望对你有一定的参考价值。

一、红黑树的定义:
R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。

1、红黑树的特性:
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
(4)如果一个节点是红色的,则它的子节点必须是黑色的。
(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。
注意:
(01) 特性(3)中的叶子节点,是只为空(NIL或null)的节点。
(02) 特性(5),确保没有一条路径会比其他路径长出俩倍。因而,红黑树是相对是接近平衡的二叉树。

2、红黑树的应用:
红黑树的应用比较广泛,主要是用它来存储有序的数据,它的时间复杂度是O(lgn),效率非常之高。
例如,Java中的TreeSet和TreeMap,C++ STL中的set、map,以及Linux虚拟内存的管理,都是通过红黑树去实现的。

3、R-B Tree时间复杂度
1)红黑树的时间复杂度为: O(lgn)。
2)高度为h的红黑树,它的包含的内节点个数至少为 2^bh(x)-1个”。因此,“一棵含有n个节点的红黑树的高度至多为2log(n+1)”。

二、红黑树的性能比较:
1、红黑树和AVL的共同点:
二叉查找树的优化,保证动态集合操作在最坏情况下时间复杂度为O(lgn);
2、查找对比:
AVL查找最好最坏都是O(lgn);
R-B Tree查找基本维持在O(lgn),最坏比AVL略差(2lg(n+1)),但远好于BST。
3、插入删除比较:
1)插入时,AVL和RBT都最多需要2次旋转;删除时,AVL最多需要lgN次旋转,而RBT最多需要3次旋转;
2)RBT旋转平衡时,需要变色操作,在O(lgN)数量级上,但操作简单、速度快;
3)二者插入删除的代价主要消耗在查找操作上,都与O(lgN)成正比;
表明:R-B Tree的总体统计性能要好于AVL。

三、R-B Tree的插入和删除
红黑树节点插入和二叉搜索树插入相似,只不过插入节点后可能会破坏红黑树平衡性,需要做平衡处理。为了继续保持红黑树的性质,可以通过对结点进行重新着色,以及对树进行相关的旋转操作,即通过修改树中某些结点的颜色及指针结构,来达到对红黑树进行插入或删除结点等操作后继续保持它的性质或平衡的目的。
1、插入操作
1)首先以二叉查找树的方法增加节点并标记它为红色;并插入二叉树时,有三种情况:
情况一:被插入的节点是根节点。
直接把此节点涂为黑色。
情况二:被插入的节点的父节点是黑色。
什么也不需要做。节点被插入后,仍然是红黑树。
情况三:被插入的节点的父节点是红色。
那么,该情况与红黑树的“特性(5)”相冲突。情况三包含了“Case 1”、“Case 2” 和“Case 3”三种情况;情况三的目的是恢复红黑树的特性,它的处理思想是:将红色的节点移到根节点;然后,将根节点设为黑色。下面介绍情况三的三种情况。
Case 1 现象:当前节点的父节点是红色,且当前节点的祖父节点的另一个子节点(叔叔节点)也是红色。
Case 1 处理策略:
(01) 将“父节点”设为黑色。
(02) 将“叔叔节点”设为黑色。
(03) 将“祖父节点”设为“红色”。
(04) 将“祖父节点”设为“当前节点”(红色节点);即,之后继续对“当前节点”进行操作。

Case 2 现象:当前节点的父节点是红色,叔叔节点是黑色,且当前节点是其父节点的右孩子
Case 2 处理策略:
(01) 将“父节点”作为“新的当前节点”。
(02) 以“新的当前节点”为支点进行左旋。

Case 3 现象:当前节点的父节点是红色,叔叔节点是黑色,且当前节点是其父节点的左孩子
Case 3 处理策略:
(01) 将“父节点”设为“黑色”。
(02) 将“祖父节点”设为“红色”。
(03) 以“祖父节点”为支点进行右旋。

2、删除操作
将红黑树T内的节点z删除。需要执行的操作依次是:首先,将T当作一颗二叉树,将节点删除;然后,通过RB-DELETE-FIXUP来对节点重新着色并旋转,以此来保证删除节点后的树仍然是一颗红黑树。
1)将T当作一颗二叉树,将节点删除;
2)通过RB-DELETE-FIXUP来对节点重新着色并旋转,以此来保证删除节点后的树仍然是一颗红黑树;
会出现3种情况:
情况一:x是“红+黑”节点。
直接把x设为黑色,结束。此时红黑树性质全部恢复。
情况二:x是“黑+黑”节点,且x是根。
什么都不做,结束。此时红黑树性质全部恢复。
情况三:x是“黑+黑”节点,且x不是根。这又可以划分了4种情况:Case 1、Case 2、Case 3、Case 4。情况三中RB-DELETE-FIXUP的思想是:将x所包含的额外的黑色不断沿树上移(向根方向移动),直到:
(01) x指向一个“红+黑”节点。此时,将x设为一个“黑”节点即可。
(02) x指向根。此时,将x设为一个“黑”节点即可。
(03) 做必要的旋转和颜色修改。

Case 1 现象:x是“黑+黑”节点,x的兄弟节点是红色。(此时x的父节点和x的兄弟节点的子节点都是黑节点)。
Case 1 处理策略:
(01) 将x的兄弟节点设为“黑色”。
(02) 将x的父节点设为“红色”。
(03) 对x的父节点进行左旋。
(04) 左旋后,重新设置x的兄弟节点。

Case 2 现象:x是“黑+黑”节点,x的兄弟节点是黑色,x的兄弟节点的两个孩子都是黑色。
Case 2 处理策略:
(01) 将x的兄弟节点设为“红色”。
(02) 设置“x的父节点”为“新的x节点”。

Case 3 现象:x是“黑+黑”节点,x的兄弟节点是黑色;x的兄弟节点的左孩子是红色,右孩子是黑色的。
Case 3 处理策略:
(01) 将x兄弟节点的左孩子设为“黑色”。
(02) 将x兄弟节点设为“红色”。
(03) 对x的兄弟节点进行右旋。
(04) 右旋后,重新设置x的兄弟节点。

Case 4 现象1:x是“黑+黑”节点,x的兄弟节点是黑色;x的兄弟节点的左孩子是红色,右孩子是黑色的。
Case 4 现象2:x是“黑+黑”节点,x的兄弟节点是黑色;x的兄弟节点的右孩子是红色的。
Case 4 处理策略:
(01) 将x父节点颜色 赋值给 x的兄弟节点。
(02) 将x父节点设为“黑色”。
(03) 将x兄弟节点的右子节设为“黑色”。
(04) 对x的父节点进行左旋。
(05) 设置“x”为“根节点”。

以上是关于红黑树算法介绍的主要内容,如果未能解决你的问题,请参考以下文章

红黑树总览

Java集合源码分析之基础:红黑树(RB Tree)

红黑树原理

红黑树原理

红黑树

红黑树插入案例