linux学习21,自平衡二叉树和红黑树的原理和特点
发表于: 2019-01-26 21:07:33 | 已被阅读: 45 | 分类于: Linux笔记
二叉搜索树的局限性
上一节较为详细的介绍了C语言中的二叉搜索树,提到数据采取二叉搜索树的结构存储,可以获得不错的搜索性能。
从根节点开始,
12 比 9 大,所以转向右节点;
12 比 29 小,所以转向左节点;
查找完毕。
这样就避免了遍历所有数值。稍微思考一下应该能发现,当二叉搜索树的每个节点都有两个子节点时,树才是最优的,这时二叉搜索树才能在存储尽可能多数值的同时,保留优秀的搜索性能。为什么呢?我们考虑一下极端情况,假设所有节点(除了最后一个节点)都只有一个子节点,如下图:
自平衡二叉搜索树
为了解决二叉搜索树的这种缺陷,自平衡二叉搜索树就被提出了。平衡二叉搜索树本质上也是一个二叉搜索树,只不过它的所有叶子节点深度差不超过 1。
节点的深度是指从根节点起,达到它一共需要经过的父节点数目。处于树最末端的节点称为叶子节点。
按照之前的分析,上图右图显然比上图作图具备更优异的性能。
红黑树
虽然自平衡二叉树更能发挥二叉搜索树的优异搜索特性,但是维护起来却非常的麻烦,很难保证插入新数据的时候也具备不错的效率,所以红黑树就被提出了。一个典型的红黑树结构如下图:
之所以说红黑树是一种
- 所有节点要么是红色,要么是黑色
- 根节点必须是黑色
- 所有叶子(NULL,or NIL)节点都是黑色的
- 红色节点的两个子节点必须是黑色(不能有连续的红色节点)
- 从根节点到任意叶子节点,黑色节点的数目是相等的
只要二叉搜索树符合以上 5 条性质,它就是红黑树。事实上,提出这 5 条性质的目的就是为了获得红黑树的“所有叶子节点的深度相差不会超过一倍”这个特性。请看下图:
如果插入和删除操作都遵循红黑树的 5 条规则,那么这个树就会始终保持是一个红黑树,即一个半平衡树,也就能维持树的插入和查询时的优异性能。之所以这么费尽心思的维护一个红黑树,是因为实践证明红黑树的这些规则遵循起来是相对简单的。
树节点的左旋和右旋
虽然红黑树的几条规则看来比较容易遵循,但是在使用C语言编程实现时,还是有些繁琐的。向红黑树插入数据时,一般分为两个步骤,首先把红黑树当作一棵普通的二叉搜索树插入数据,然后再进行旋转变换以及重新着色的操作,调整二叉树仍然是一个红黑树。
应该明白,红黑树也是一棵二叉搜索树,所以二叉搜索树的性质红黑树也应遵循。在向红黑树插入数据后的变换和重新着色操作中,着色显然不会影响二叉搜索树的性质,“红黑色”只是节点的一个标记而已,它不影响节点记录的数据,也不影响节点间的相对关系。真正改变树结构的是“旋转”操作,应该尽力避免会破坏
只要在努力把二叉搜索树变换成红黑树的过程中,始终遵循不破坏
小节
我们费尽心思的琢磨出红黑树,又提出看起来非常拗口的红黑树 5 条性质,其实目的只有一个:尽可能