一:AVL树
也就是平衡二叉树,该二叉树为了优化查找的性能,会让每个结点的左右子树的高度差维持在1以内,也就是小于等于1。因为我们在二叉查找树上查找数据的时候,是类似二分法的,那么我们每次折半的区间长度就会决定了我们查找的效率,从概率的角度讲,在未知的情况下肯定是一半一半获得的效率最高。所以在二叉查找树中,决定查找效率就是树的高度,为什么呢?
其实我们可以这样想,因为我们每次在二叉树中查找的时候,没经过一层,总是选择的其中一个结点进行的比较,也就意味着另外一个结点是我们跨越的步长,前面我们说到过一半一半的效率肯定是最高的,那么维持这样的形式产生的结果就是AVL树,因为在尽可能的维持每步跨越结点一样的时候,二叉查找树就比较自然的演变成了AVL树,因为在左右子树高度差小于等于1的情况下,结点会尽可能的填满每一个父结点,而不会出现二叉查找树的一边偏向的问题。
综上所述,AVL树是一种二叉查找树的优化结构,旨在提高查找的效率。但是带来的问题是需要在插入结点和删除结点的时候维持整棵树的平衡性,在有的情况下,这可能得不偿失,也就是意味着,我们维护二叉查找树的平衡性的代价大于最后我们查找所获得的额外的收益。
二:B-树
前面我们陈述了一个问题,那就是树的结点的高度差会影响结点的查找效率,那么下面我们再来分析一个相关的因素,那就是整棵树的高度。我们可以这样来想因为二叉查找树在每个结点都存放了数据,那么在最好的情况下查找到数据就是在根节点的情况下,但是这种情况在大量的查找下发生的概率是极低的,反而大部分的情况我们都会查找到叶子结点,为什么呢?
其实如果是在大量操作的情况下,那么从概率的角度出发就是很有说服力的,我们可以看到越接近叶子结点每层的结点数就越多,我们先假设查找的数据是随机并且等概率的(当然只是一个粗略的估计),那么结点数越多的层数始终会出现一种统计上的优势,即大概率发生,甚至必定发生,显然叶子结点层是拥有最多的结点的层,并且越靠近叶子结点的层数的结点数就越多,那么我们有理由认为查找的结果大概率会发生在叶子结点或者靠近叶子结点的地方。所以整棵树的高度就显得尤为重要了,为什么呢?因为我们在查找的时候树的高度代表我们要检索的次数,显然好似树越低我们查找到就越快。
而且B-树的数据如果是存储在外存的,那么磁盘的IO次数将是效率的决定行因素,所以树的高度越低代表需要I/O的次数越少。
综上所述:B-树是一棵多叉平衡搜索树,旨在比AVL树能够拥有更低的树高,提高查找的效率,但是同AVL树一样,面对插入和删除数据的操作后需要维持平衡,这可能带来一些得不偿失的情况。其次B-树可以被采用在外存的数据查询上,因为树高比较低,这样就可以减少磁盘的I/O次数。
三:RB树(红黑树):
相当于是一个3叉的搜索树,因为在一些相当多的情况下,我们可以只用三叉就不会产生很高的树,那么我们就决定采用3叉树,但是前面我们提到了一个问题,那就是插入和删除数据的时候,会带来繁琐的调整整棵树平衡性的操作。所以在一些情况下,我们做出了时间和效率的权衡,我们采用一种3叉B-树的变体,也就是红黑树。
红黑树的优点是,不是绝对的平衡,但是又加入了限制的条件,可以让结点间的树高差距限定在一定的范围内(最高高度结点的高度不高于最低高度结点高度的两倍)。并且采取了将B-树用二叉树的形式表现出来,大大简化了插入和删除的操作。
综上所述:红黑树其实就是3叉B-树,只是进行了一个优化,使其查找,插入,删除的总体效果得到优化。
四:B+树:
应用于数据库等将数据存放在外存的情况下,这种结构是对B-树进行的一个变化,使其更加的适合在磁盘上数据的插入、删除、查询等。因为我们前面说过当数据存放在外存的时候,限制查询等操作的就不再是内存中的有限操作了,而是磁盘的I/O,因为磁盘的速度是完全不可能与CPU和内存打交道的速度相提并论的。所以我们有一个最大的需求,那就是减少I/O次数,基于此我们采用了多叉的情况(比B-树更多叉),这就使得树可以更矮,其次我们B+树的数据全部存储在叶子结点,中间的结点只是存储键值,不存储数据,那么也就是在相同的磁盘块的大小的情况下,我们可以存储更多的索引,这样也可以减少磁盘的I/O次数。然后我们在树的叶子结点间进行了一个链接的操作,这是便于我们进行范围查找,因为在B-树中进行范围查找将是十分困难的,需要采用中序遍历,非常繁琐,基于这个考量增加了叶子结点间的指针(因为数据库中范围查找是应用得相当多。)
五:B*树:
B+树的变体,增加了空间利用率的下限。