树结构(二)——二叉搜索树、平衡二叉树、红黑树、B树、B+树

        本篇博客内容略多,涵盖面比较广,小编也是正在学习中,故读者在发现有错误的说法,欢迎在评论区指出。此外,树结构本身就是一个非常复杂的大家庭,各种规则,各种条件,望大家不要气馁,加油,奥利给。

一、二叉搜索树

        二叉搜索树是一种特殊的二叉树,它的特点是:

  1. 对于任意一个节点p,存储在p的左子树的中的所有节点中的值都小于p中的值
  2. 对于任意一个节点p,存储在p的右子树的中的所有节点中的值都大于p中的值

        图例:

        基于二叉搜索树的特性,采用中序遍历的方式可以使得遍历结果是按照从小到大的顺序排列的

二、平衡二叉树

        平衡二叉树时间复杂度最好的情况下是O(log(n)),但是最坏的情况是O(n),例如:

       针对上述情况,有大牛提出了平衡二叉树,即AVL树,所谓平衡是指,对于树中的每一个位置p,p的孩子的高度最多相差1。

       例如:a的左高度等于3,右高度等于1,差值为+2,属于不平衡中的左偏。

       下面,小编会介绍四种不平衡的状态,并针对这种不平衡状态给出相应的解决方案:

 

(1)不平衡态(LL):   从上到下都是左边高 

         解决方案(右旋):这个变换就像是以10为中心,向右旋转,使10变成根节点,10的左子树不变,右子树变成了20,多余出的15正好挂在由于变换失去了左子树的20的左边。变换后结点从左到右的顺序依然没有变,所以15是正好挂在20的左边的。

                                                          

(2)不平衡态(RR):   从上到下都是右边高 

         解决方案(左旋):左旋与右旋的形式差不多,只不顾是反着来的。相当于进行一次左旋转

       

(3)不平衡态(LR):   从上到下先左高后右高 

         解决方案(左旋后右旋):第一次相当于对5、10、15、17这棵子树进行了一次左旋,旋转方式与之前的RR方式相同,就像是以15为中心向左旋转,旋转的结果使得整棵树变成了LL的不平衡形态,然后再按照LL的右旋方式对整棵树操作。

     

(4)不平衡态(RL):   从上到下先右高后左高 

         解决方案(右旋后左旋):RL同样是LR的相反模式,先将22、25、30、40这棵子树进行LL旋转,再将整棵树进行RR旋转。

       PS:下列特殊情况也是非平衡状态,因为左子树与右子树的高度相差2。

三、红黑树

       本节小编将重点介绍红黑树的特性,红黑树本身是一个难度系数较大的数据结构,尤其是删除节点,规则更是复杂,大家如果想深究还是需要下苦功夫的。红黑树的应用场景包括,C++中的STL、Java的TreeMap、nginx中用红黑树管理timer、epoll在内核中的实现用红黑树管理事件块。讲道理小编对红黑树的了解也是非常肤浅的,但是为了blog的完整性,还是抛出来一些相关概念。

       红黑树有如特性:

  1. 根节点必须为黑色
  2. 父子不能同为红色
  3. 从任何一节点出发,到达叶子节点经过的黑色节点数量一致

       红黑树插入时主要观察插入节点的父节点,祖父节点,及叔叔节点。

       插入规则:默认插入节点为红色

(1)插入节点为根节点: 染黑插入节点

(2)插入节点Parent为黑: 直接插入

(3)插入节点Parent为红: 根据Uncle的情况分类

         1. Uncle是红色的: 染黑Uncle和Parent,染红GrandParent

         2. Uncle是黑色的:

                  1. 三角型: 旋转Parent,执行直线型的操作

                  2. 直线型: 旋转GrandParent,交换插入节点与GrandParent的颜色

       删除规则:

(1)删除节点是叶节点,替换节点为null

(2)删除节点有一个子代,替换节点为该子代

(3)删除节点有两个子代,替换节点为后继节点(successor)

(4)执行删除节点,根据删除节点和替换节点的情况分类讨论

         1. 若删除节点有两个后代: 交换替换节点与删除节点键值,对替换节点进行删除操作

         2. 若删除节点无两个后代:

                  1. 删除节点是树根: 直接删除或替换

                  2. 删除节点是叶节点: 若删除节点是黑色,则为双黑,修复双黑

                  3. 删除节点有一个后代: 若不是双黑情况,染黑替换节点

       小编对红黑树的插入删除介绍的较少,读者如果有兴趣可以参考该视频

四、B树

       4.1 2-3树

       在介绍B树之前,先抛出2-3树这个概念。2-3树是一种多路查找树,2和3的意思是2-3树包含两种节点。

(1)2节点包含一个元素两个孩子(或者没有孩子),其特点如下:

  1. 左子树包含节点的元素值小于该节点的元素值,右子树包含节点的元素值大于该节点的元素值
  2. 2节点要么有两个孩子,要么没有孩子,不允许有一个孩子

(2)3节点包含一大一小两个元素(两个元素按大小排列好)和三个孩子(或者没有孩子),其特点如下:

  1. 左子树包含的节点的元素值小于该节点较小的元素值,右子树包含的节点的元素值大于该节点较大的元素值,中间子树包含的节点的元素值介于这两个元素值之间
  2. 3节点要么有三个孩子,要么没有孩子,不允许有一个孩子

(3)2-3树所有的叶子节点在同一层次

       例如:

 

      4.2 B树定义        

        B树也是一种平衡的多路查找树,2-3树是B树的特例,我们把树中节点最大的孩子数目成为B树的阶,通常记作m,例如2-3树的阶就是3,因为最大的孩子数目是3。

        一棵m阶B树特征如下:

  1. 树中每个节点至多有m个子树
  2. 若根节点不是终端节点,则至少有两棵子树
  3. 除根节点的所有非叶节点至少有[m/2](该符号是向上取整的意思)棵子树,即至少有[m/2]-1个关键字
  4. 所有叶子节点都出现在同一层次上,不存储任何信息。
  5. 所有非叶节点结构如下:

      4.3 B树插入 

        下面我们给定一组关键字{20,30,50,52,60,68,70},演示下一棵3阶B树的创建过程。

      4.4 B树删除 

        我们根据删除节点的位置,可以分为关键字在终端节点和不在终端节点上两种情况。

(1)在终端节点上

        1、删除节点内关键字数量大于[m/2]-1,这时删除这个关键字不会破坏B树的定义要求,所以直接删除。

  直接删除9即可

        2、删除节点内关键字数量等于[m/2]-1,并且其左右兄弟节点中存在关键字数量大于[m/2]-1的节点,则去兄弟节点中借关键字

        3、删除节点内关键字数量等于[m/2]-1,并且其左右兄弟节点中不存在关键字数量大于[m/2]-1的节点,则需要进行节点合并

 

(2)不在终端节点上:先转换为终端节点再做处理

        先介绍相邻关键字,对于不在终端节点的关键字,它的相邻关键字等于其左子树中值最大的关键字或右子树中值最小的关键字

        1、左右子树关键字数量不都等于[m/2]-1

        2、左右子树关键字数量都等于[m/2]-1,则将两个左右子树节点合并,然后删除待删除关键字

        有关于B树,读者可以参阅该视频

五、B+树

        B+树和B树非常类似,唯一的区别在于B树的节点中存储着信息,而B+树只在叶子节点存储信息。

        结构上:

  1. B树中关键字集合分布在整棵树中,叶节点中不包含任何关键字信息,而B+树关键字集合分布在叶子结点中,非叶节点只是叶子结点中关键字的索引
  2. B树中任何一个关键字只出现在一个结点中,而B+树中的关键字必须出现在叶节点中,也可能在非叶结点中重复出现

        性能上(也即为什么说B+树比B树更适合实际应用中操作系统的文件索引和数据库索引?)

  1. 不同于B树只适合随机检索,B+树同时支持随机检索和顺序检索
  2. B+树的磁盘读写代价更低。B+树的内部结点并没有指向关键字具体信息的指针,其内部结点比B树小,盘块能容纳的结点中关键字数量更多,一次性读入内存中可以查找的关键字也就越多,相对的,IO读写次数也就降低了。而IO读写次数是影响索引检索效率的最大因素
  3. B+树的查询效率更加稳定。B树搜索有可能会在非叶子结点结束,越靠近根节点的记录查找时间越短,只要找到关键字即可确定记录的存在,其性能等价于在关键字全集内做一次二分查找。而在B+树中,顺序检索比较明显,随机检索时,任何关键字的查找都必须走一条从根节点到叶节点的路,所有关键字的查找路径长度相同,导致每一个关键字的查询效率相当
  4. (数据库索引采用B+树的主要原因是,)B-树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题。B+树的叶子节点使用指针顺序连接在一起,只要遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作(或者说效率太低)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章