二叉搜索树、AVL树、RB-tree(红黑树)

参见:《STL源码剖析》

 

(一)二叉搜索树

二叉树:一个二叉树如果不为空,便是由一个根节点和左右二叉子树组成。

二叉搜索树:1)是一颗二叉树;2)任何节点的键值一定大于其左子树中的每一个节点的键值,并小于其右子树中的每一个节点的键值。

查找:

《二叉搜索树、AVL树、RB-tree(红黑树)》

插入:

《二叉搜索树、AVL树、RB-tree(红黑树)》

删除:

1)若是叶子节点直接删除,修改父节点的指针。

2)若只有一个子节点,直接将其子节点连至其父节点

《二叉搜索树、AVL树、RB-tree(红黑树)》

3)若有两个子节点,以右子树中的最小值取而代之。

《二叉搜索树、AVL树、RB-tree(红黑树)》

 

 

(二)AVL树

AVL树是一个“加上额外平衡条件”的二叉搜索树。其平衡条件的建立是为了确保整棵树的深度为O(logN)。AVL树要求任何节点的左右子树高度相差最多为1。如图,只要调整其中最深的那个节点(18),便可使整棵树重新获得平衡。

《二叉搜索树、AVL树、RB-tree(红黑树)》

“平衡被破坏”意味着X(最深节点)的左右两棵子树的高度相差为2,因此我们可以轻易将情况分为4种。

《二叉搜索树、AVL树、RB-tree(红黑树)》

情况1,4彼此对称,成为外侧插入,可以采用单旋转操作调整解决。情况2,3彼此对称,成为内侧插入,可以采用双旋转操作调整解决。

单旋转:

《二叉搜索树、AVL树、RB-tree(红黑树)》

双旋转:

《二叉搜索树、AVL树、RB-tree(红黑树)》

 

 

(三)RB-tree(红黑树)

红黑树,不仅仅是一个二叉搜索树,而且必须满足以下规则:

1、每个节点不是红色就是黑色(图中深色条纹代表黑色,浅色条纹代表红色)

2、根节点为黑色

3、如果节点为红色,其子节点必须为黑色。

4、任何一个节点至NULL(树尾端)的任何路径,包含之黑色节点树必须相同。

《二叉搜索树、AVL树、RB-tree(红黑树)》

 

为了方便讨论,假设新节点为X,其父节点为P,祖父节点为G,伯父节点为S,曾祖父节点为GG。现在,根据红黑树规则4,X必为红。若P亦为红,则G必为黑。于是,根据X的插入位置及外围节点(S和GG)的颜色,有以下四种考虑。

状况1:S为黑且X为外侧插入——先对P,G做一次单旋转,并更改P,G颜色。

《二叉搜索树、AVL树、RB-tree(红黑树)》

状况2:S为黑且X为内侧插入——先对P,X做一次单旋转并更改X,G颜色,再将结果对G做一次单旋转。

《二叉搜索树、AVL树、RB-tree(红黑树)》

状况3:S为红且X为外侧插入——先对P和G做一次单旋转,并改变X的颜色。若GG为黑,结束;若GG为红,转状况4.

《二叉搜索树、AVL树、RB-tree(红黑树)》

状况4:S为红且外侧插入——先对P和G做一次单旋转,并改变X的颜色。若此时GG为红,还得持续往上做,直到不再有父子连续为红的情况。

《二叉搜索树、AVL树、RB-tree(红黑树)》

一个由上而下的程序:

为了避免出现状况4“父子节点皆为红色”的情况持续向RB-tree的上层结构发展,形成处理时效上的瓶颈,我们施行了一个由上而下的程序:假设新增节点为A,那么就延着A的路径,只要看到有某节点X的两个子节点皆为红色,就把X改为红色,并把两个子节点改为黑色

《二叉搜索树、AVL树、RB-tree(红黑树)》

但是如果X的父节点P亦为红色(注意,此时S必为黑),就像状况1

一样做一次单旋转并改变颜色,或像状况2一样地做一次双旋转并改变颜色。

《二叉搜索树、AVL树、RB-tree(红黑树)》

在此之后,节点35的插入就很单纯了:要么直接插入;要么插入后(若X节点为红)再一次旋转(单双皆可能)即可。

 

 

 

    原文作者:AVL树
    原文地址: https://blog.csdn.net/Damage233/article/details/81179656
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞