一、二叉查找树
二叉查找树(BST)具备什么特性呢?
1.左子树上所有结点的值均小于或等于它的根结点的值。
2.右子树上所有结点的值均大于或等于它的根结点的值。
3.左、右子树也分别为二叉排序树。
1.查看根节点9:
2.由于10 > 9,因此查看右孩子13:
3.由于10 < 13,因此查看左孩子11:
4.由于10 < 11,因此查看左孩子10,发现10正是要查找的节点:
二叉查找树的缺陷:
假设初始的二叉查找树只有三个节点,根节点值为9,左孩子值为8,右孩子值为12:
接下来我们依次插入如下五个节点:7,6,5,4,3,如下:
二、红黑树的性质
红黑树(Red Black Tree)是一种自平衡的二叉查找树,除了符合二叉查找树的特性外还具有以下特性:
1.节点是红色或黑色。
2.根节点是黑色。
3.每个叶子都是黑色的空节点(NIL节点)。
注: 叶子与叶子节点是两个概念,叶子不是一个节点,可以理解为没有数值的空节点,也就是图中的NIL。
4 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
5.从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
下图中这棵树,就是一颗典型的红黑树:
三、红黑树的插入过程
1.插入位置为根节点(第一个值),红色变成黑色即可。
2.插入位置父节点为黑色节点,直接插入一个红色节点即可。
3.插入位置父节点与父节点的同级节点(下称叔父节点)均为红色节点,需要改变父节点和叔父节点的颜色为黑色,同时将父节点的父节点(下称祖父节点)改变为红色。如果祖父节点为根节点或祖父节点的父节点也为红色,需要进一步变化。
4.插入位置父节点为红色,叔父节点为黑色或者空节点,同时新增节点是其父节点的左节点(右节点)而父节点又是其父节点的左子节点时,需要使用到右旋转(先左后右旋转)。
5.插入位置父节点为红色,叔父节点为黑色或者空节点,同时新增节点是其父节点的左节点(右节点)而父节点又是其父节点的右子节点时,需要使用到先右后左旋转(左旋转)。
四、红黑树的删除过程
1.删除节点为红色,直接进行删除。
2.删除的节点为黑色,其儿子节点是红色。将当前节点删除,将它的儿子从红色改变成黑色即可。
3.删除的节点为黑色,其儿子节点也是黑色。
3-1 叔父节点为红色,删除父节点是其父节点的左子节点(右节点)时,儿子节点是删除父节点的左子节点(右子节点)时,子节点覆盖父节点 ,进行一次左旋(右旋)。(此时,爷爷必为黑!)
3-2 叔父节点为黑色
3-2-1 祖父节点为红色,两个侄子节点为黑色。子节点覆盖删除的父节点,交换祖父节点和叔父节点的颜色。
3-2-2 祖父节点为黑色,两个侄子节点为黑色。祖父染成子节点的颜色,子节点染成黑色,叔叔染成红色 。
3-2-3 祖父节点颜色随意,叔父节点为右节点,左侄子为红色。红侄先右旋后左旋 ,红侄染成父节点颜色,父节点染成黑色。
3-2-4 祖父节点颜色随意,叔父节点为右节点,右侄子为红色。红侄左旋,叔叔染成父节点颜色,红侄染成黑色。
3-2-5 祖父节点颜色随意,叔父节点为左节点,左侄子为红色。红侄进行一次右旋 ,红侄染成黑色 ,交换叔叔和祖父的颜色 。
3-2-6 祖父节点颜色随意,叔父节点为左节点,右侄子为红色。红侄先右旋后左旋 ,红侄染成父节点颜色,父节点染成黑色 。
五、红黑树相比于BST和AVL树有什么优点
红黑树是牺牲了严格的高度平衡的优越条件为代价,它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能。
红黑树能够以O(log n)的时间复杂度进行搜索、插入、删除操作。此外,由于它的设计,任何不平衡都会在三次旋转之内解决。
当然,还有一些更好的,但实现起来更复杂的数据结构能够做到一步旋转之内达到平衡,但红黑树能够给我们一个比较“便宜”的解决方案。
相比于BST,因为红黑树可以能确保树的最长路径不大于两倍的最短路径的长度,所以可以看出它的查找效果是有最低保证的。在最坏的情况下也可以保证O(logN)的,这是要好于二叉查找树的。因为二叉查找树最坏情况可以让查找达到O(N)。红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高,所以在插入和删除中所做的后期维护操作肯定会比红黑树要耗时好多,但是他们的查找效率都是O(logN),所以红黑树应用还是高于AVL树的. 实际上插入 AVL 树和红黑树的速度取决于你所插入的数据。如果你的数据分布较好,则比较宜于采用 AVL树(例如随机产生系列数),但是如果你想处理比较杂乱的情况,则红黑树是比较快的。