数据结构之重要树总结(红黑树、B/B+树等)

 众所周知,二叉树在数据结构中的分量举足轻重。之所以分量如此重,是因为在实际中有很多情况用此数据结构会产生很多好处。本文主要对二叉搜索树、平衡二叉树、红黑树、BB+B*)树进行总结,因为这几种树的概念十分重要,了解它们对于其他学科的知识将会有更进一步的理解。

    树结构优劣最重要的衡量标准就是操作的时间复杂度,而这些操作的时间复杂度与树的高度成正比。

    首先看一张图

《数据结构之重要树总结(红黑树、B/B+树等)》

图1 多种树的关系概略图

    这张图概略地描绘了这些树的关系,I、II、III、IV、V均表示两种树之间的关系。以下我会一点一点地讲述为什么会出现这些树。

 首先是树和二叉树,这个概念很简单也很基础,在此不再赘述,只提一点二叉树不是树的一种特殊情况。原因百度百科有,我亦不表,因为我觉得这个概念并不重要,不管是不是一种数据结构,二叉树始终是从树中衍生出的。

  从这里开始进入本文主要内容。

  接下来介绍二叉搜索树。二叉搜索树又称二叉排序树、二叉查找树。

        一、为什么会出现二叉搜索树?

          对于数据的操作来说,最主要的无非就是查找、插入和删除。

          假设我们有一个数据集,它是顺序存储(包括线性表和链表两种方式)的,那么插入和删除操作对于这种结构来说,效率是可以接受的,但 是查找效率呢?一旦数据集中数据无序将使查找效率很低。那自然我们就想到让数据集有序,好,请继续看……

          如果数据集是有序的也是顺序存储的,查找我们就可以采取二分法等来实现,效率确实很提高很多,但 是,也正是因为有序,在插入和删 除操作上就需要耗费大量时间。这就迫使我们寻找能兼顾查找、插入和删除操作效率的方法,于是二叉搜索树登场了。

        二、二叉搜索树与二叉树的关系(这里也就是图1中关系I

          图1中关系I表示二叉搜索树是在二叉树的基础上定义的,只不过附加了以下条件(二叉搜索树不为空时):

     对于任意结点

     1、若其左子树不空,左子树上所有结点的值均不大于此结点的值;

    2、若其右子树不空,右子树上所有结点的值均不小于此结点的值;

    3、其左右子树也分别为二叉搜索树。

    三、二叉搜索树性能

     最好的时候是完全二叉树,时间复杂度是O(log2n)最差的时候线性连接的情况,时间复杂度O(n) 

 四、二叉搜索树操作(操作代码此文不表,以下所有同)

         操作中查找和插入都很简单,难点在于删除操作,删除有三种情况:
         1、删除叶子结点;
         2、删除仅有左子树或者右子树的结点;
         3、删除既有左子树又有右子树的结点。
         情况1直接删除就行,情况2在删除后将其所存在的那个子树直接移到删除结点的位置即可,情况3选取删除结点的直接前驱(也就是其左子树中最大值)或者直接后继(右子树中最小者)替换删除结点,习惯上选取直接前驱。


     二叉搜索树介绍完了,下面开始介绍平衡二叉树(AVL树)。

     一、为什么需要平衡二叉树?

         由于二叉搜索树的最差情况效率并不高,所以想把它构建成一个平衡的二叉搜索树,一旦平衡,树的高度自然降低,操作的时间复杂度也会 降低。

     二、平衡二叉树与二叉搜索树的关系(这里也就是图1中关系III

                   图1中关系II表示平衡二叉树是在二叉搜索树的基础上定义的,当然也一定是附加了条件:
         1、每个结点的左子树与右子树的高度差至多等于1。

     三、平衡二叉树的性能

         是平衡二叉树查找、插入和删除的时间复杂度都是
O(log
2
n),这已经是一种比较理想的一种动态查找表算法。目前平衡二叉树与红黑树 在二叉树中效率已是最佳。

     四、平衡二叉树的操作

         1、平衡二叉树有两个名词:平衡因子与最小不平衡子树。这里解释一下:
         1)平衡因子(BF):二叉树上结点左子树深度减去右子树深度的值。平衡二叉树上任意结点的BF只可能为-1、0和1。
         2)最小不平衡子树:以距离插入节点最近的且平衡因子的绝对值大于1的结点为根的子树。
         《数据结构之重要树总结(红黑树、B/B+树等)》 
图2 新插入结点的平衡二叉树
         图2是我从网上截取的一个图片,除开结点39,其他结点构成一个平衡二叉树。图2中每个结点上方都有一个数字,这就是平衡因子,如此时 结点50的平衡因子就是2。按照定义结点43、30、39组成了最小不平衡子树。
         2、查找、插入和删除
         这里给一个链接,我觉得还是挺好的,挺容易明白的。点击这里
         
     继平衡二叉树之后,下面要讲一个和平衡二叉树关系极为密切的一种树——
红黑树

    一、红黑树与二叉搜索树的关系(这里也就是图1中关系II

                图1中的关系II表示红黑树是在二叉搜索树的基础上定义的,附加的条件如下:
         1、结点要么是黑的,要么是红的;
         2、根节点是黑的;
         3、叶子结点,即NIL结点是黑的;
         4、如果一个结点是红色的,那么它的两个儿子几点是黑色的;
         5、对任意结点,从它到叶子结点(NIL)的所有路径上都有相同数目的黑色结点。

     二、红黑树与平衡二叉树的关系(这里也就是图1中关系IV

               1、红黑树与平衡二叉树整体类似,平衡二叉树是严格的平衡,而红黑树放宽了平衡二叉树的平衡条件,不要求“完全平衡”。平衡二叉树的平 衡在于平衡因子,而红黑树的平衡主要体现在上面的第5条,即基于颜色。引入“颜色”的概念也就是为了简化平衡条件,降低旋转的要求,任何不平衡都能在三次旋转以内解决,所以相对于平衡二叉树,给我们提供了“比较便宜”的方案。
               2、二者的插入、删除和查找操作的时间复杂度均为O(log2n)
               3、红黑树的统计性能要好于平衡二叉树,这也是STL中map和set使用红黑树实现的原因;平衡二叉树在一些极端情况下性能要比红黑树好。


        下面介绍一下B树以及B+树。它们并不是二叉树,而是多叉树。
        一、为什么需要B树呢?
              引入这个新类型的树你的第一反应一定是要它何用。其实在理解了B树的性质后你就能一下子明白了。这里还是先说明一下B树因何而生。
              其实,B树主要用于内外存交换数据,如数据库中的索引。因为它的特性极大地减少了磁盘I/O访问次数,节省了这辈分的消耗,提高了效率。
       二、B树的性质
              先来了解下“阶”的概念,一个结点最多可以有m个孩子结点,就称此树是m阶的。
              对于一个m阶B树,性质如下:
              1、如果根节点不是叶子结点,则至少应该有两颗子树;
              2、m/2向上取整 <= 每个结点的孩子个数的取值 <= m,即要求至少半满;关键字个数比孩子数少1;
              3、所有的叶子结点在同一层次;
              4、每个结点都包含三个属性:n、K、A。n是这个结点包含的关键字个数,如下图每个结点第一个数字都代表个数;K就是关键字,如图中的 K1、K2、K3分别代表3、5、8;A是这个结点指向孩子结点的指针,如图中的A0~A3。每个关键字的左边的A指向的子结点上所有关键字都比它小,右边的都比它大,如5左边的是A1,A1指向的是4比5小,右边的是A2,A2指向的是6、7组成的结点,都比5大。
《数据结构之重要树总结(红黑树、B/B+树等)》
        三、B树与平衡二叉树的关系(图1中的关系V)
               它们二者的关系并不如前所述的一系列关系密切,B树是在平衡二叉树的思想上的一个扩展,从平衡二叉树到平衡多叉树。
               B树与平衡二叉树、红黑树有一个相似点:高度是O(lgn)。但是B树其实是O(logmn)。这个m一般来说要比2大很多,所以B树的高度一般不高,不高才有在内外存数据交互过程中大展拳脚的机会,你所做的查找次数总不会超过这个高度,极大减少了内外存交互次数。
               B树的插入、删除和查找操作的时间复杂度也为O(lgn)
       四、B+树
             既然说到B树,那么势必要说一下B+树,因为B+树与B树关系太密切了,现在数据库中多用B+树实现索引,取代了B树实现索引,原因看完下面的知识就一目了然了。
             B+树与B树的关系
             B+树产生的原因在于:B树的中序遍历需要太多次I/O访问次数了。你每次中序遍历只能从根节点第一个关键字开始,遍历了该关键字左孩子以 后要返回到父结点遍历它的右孩子,如此反复,直到结束。所以需要有一种方法解决这个问题。那么问题来了,为什么要这么在意中序遍历?就是       因为你中序遍历以后的序列是整个树的所有关键字的一个从小到大排序的序列,现在你明白为什么B+树更适合做索引了么?它更适合范围查找。
             B+树与B树差异在于:
             1、每个结点除了自身关键字外,还需要将父结点关键字保存起来;
             2、所有的叶子结点包含所有的关键字信息,以及指向这些关键字记录的指针,叶子结点本身按照自小而大的顺序连接(每个叶子结点都有一  个指针指向下一个叶子结点);
             3、所有的分支结点都可以看做是索引,它只是其孩子结点的最大或者最小的关键字。
             看了下图你就明白了
《数据结构之重要树总结(红黑树、B/B+树等)》

        学习B树可以先看一下2-3树和2-3-4树,这里不详细介绍了。
        以下是我觉得很不错的几篇博客
        http://blog.csdn.net/v_JULY_v/article/details/6530142
        http://blog.csdn.net/eric491179912/article/details/6179908

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