红黑树Read-Black Tree
一、
红黑树也是一颗AVL树(平衡二叉树),树中的节点只有两种颜色:红色和黑色。
红黑树具有以下的特性:
- 每个节点要么是红色,要么是黑色;
- 根节点是黑色的;
- 每个叶子节点(NULL)都是黑色的空节点;
- 从根节点到叶子节点,不会出现两个连续的红色节点(即两个红色节点不能直接相连);
- 从任何一个节点出发,到叶子节点,这条路径上都有相同数量的黑色节点;
其实红黑树并不是严格意义下的平衡树(左右子树的高度差的绝对值不超过1)(这个我们可以从之后的图看到),通过性质5我们可以看到,从根节点到叶子节点的每条路径上,黑节点的的数目是相同的,所以红黑树可以称为是黑色完美平衡
可以对照上面5点性质,下图是一棵红黑树
对照上述5条性质,这的确是一颗红黑树,具有平衡树的特点。
二、
红黑树能够实现自平衡,主要靠一下三种操作:左旋、右旋和变色。
2.1 红黑树的查询操作
因为红黑树本身也是一棵二叉搜索树,所以红黑树的搜索查询的过程和二叉搜索树是相同的:比较查询节点和当前节点的Value大小,然后递归地比较下去;
2.2 红黑树的插入节点
红黑树的节点插入是最复杂的。我们首先按照二叉搜索树插入的规则插入新节点,然后为了满足红黑树的所有性质,我们再进行调整,可以按照以下情形分类讨论。
有一点需要大家注意:插入的节点一定是红色的,因为受到了性质5的限制。
2.2.1 插入一棵空树
插入节点作为整棵树的根节点,并且把根节点涂成黑色(满足性质2)
2.2.2 插入节点的父亲节点是黑色的
插入节点是红色的,其父亲节点本身就是黑色的,对照红黑树的5条特性,我们发现直接插入节点即可,不需要进行调整。如下图所示(插入节点14):
2.2.3 插入节点的父亲节点是红色的
我们先按照二叉搜索树的插入规则进行插入,如下图所示:
我们观察一下,这种情况下会出现哪些问题?
我们发现现在这棵红黑树违反了性质4(红色节点不能直接相连),我们需要在此基础上调整:变色+旋转
2.2.3.1 父亲节点的兄弟节点,即叔叔节点(节点27)是红色的
- 把父亲节点设置为黑色(22)
- 把叔叔节点设置为黑色(27)
- 把祖父节点设置为红色(25)
- 把祖父节点设置为当前要操作的节点
通过这次变色处理,我们发现方框中的子树满足了红黑树的特性,但放到整棵树中依然有问题(父亲节点(17)和叔叔节点(8)是红色的),我们再调整一次,如下图所示:
这里需要注意:祖父节点(13)是根节点,根节点要保证是黑色的,所以祖父节点我们就并不变色了。
2.2.3.2 父亲节点的兄弟节点,即叔叔节点(节点27)是黑色的
这种情况下又分为两种情况
2.2.3.2.1 新插入的节点为父节点的左子节点,右旋
(1)、把父节点变成黑色;
(2)、把祖父节点变成红色;
(3)、以祖父节点旋转
2.2.3.2.1 新插入的节点为父节点的右子节点,左旋
这里发现左旋后,又回到了父亲节点为红色和叔叔节点为黑色,并且 新插入的节点为父节点的左子节点,那么我们再进行右旋操作即可;
总结如下:
到此位置,红黑树的插入操作就总结完了,至于红黑树的删除操作,后续再总结。
作者:Ryanjie
出处:http://www.cnblogs.com/ryanjan/
本文版权归作者和博客园所有,欢迎转载。转载请在留言板处留言给我,且在文章标明原文链接,谢谢!
如果您觉得本篇博文对您有所收获,觉得我还算用心,请点击右下角的 [推荐],谢谢!