AVL树之外,另一个被广泛运用的平衡二叉搜索树是RB-tree。所谓红黑树,不仅是一个二叉搜索树,它还满足以下性质:
1. 每个节点是红色或黑色;
2. 根是黑色;
3. 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点);
4. 从任一节点到NULL(树尾端)的任何路径都包含相同数目的黑色节点;
5.每个叶子节点(或NIL)均为黑。
为什么选择红黑树作为底层实现
红黑树是一种类平衡树, 但它不是高度的平衡树, 但平衡的效果已经很好了. 补充说明另一种 AVL 树, 我之前的博文: 《编程珠玑,字字珠玑》读书笔记完结篇——AVL树
用过 STL map 么, 你用过 linux 么(这个说大了), 他们都有红黑树的应用. 当你对搜索的效率要求较高,并且数据经常改动的情景,你可以用红黑树, 也就是 map.
至于, 为什么不用 AVL 树作为底层实现, 那是因为 AVL 树是高度平衡的树, 而每一次对树的修改, 都要 rebalance, 这里的开销会比红黑树大. 红黑树插入只要两次旋转, 删除至多三次旋转. 但不可否认的是, AVL 树搜索的效率是非常稳定的. 选取红黑树, 我认为是一种折中的方案.
1 红黑树的插入
插入节点的关键是:
1. 插入
新节点总是红色节点
;这是为了维护性质4;
2. 如果插入节点的父节点是黑色,能维持性质;
3. 如果插入节点的父节点是红色,破坏了性质。 故插入算法就是通过重新着色或旋转,来维持性质。
2. 如果插入节点的父节点是黑色,能维持性质;
3. 如果插入节点的父节点是红色,破坏了性质。 故插入算法就是通过重新着色或旋转,来维持性质。
假如我们为一棵红黑树分别插入3, 8, 35, 75,如下图所示:
情形1:以“左左
外侧
”插入节点3,且新插入的节点3为红;因为其父节点5为红(不满足性质3),那么仅需对P,G进行一次单旋转,再改变P,G的颜色,此时平衡性质得以维持;如下图所示:
情形2:以“左右内侧”插入节点8,且新插入的节点8为红;我们先对P,X做一次单旋转,并更改G,X的颜色;再将结果对G做一次单旋转,即可维持平衡的性质;如下图所示: