B树、B+树、红黑树、AVL树

定义及概念

B树

二叉树的深度较大,在查找时会造成I/O读写频繁,查询效率低下,所以引入了多叉树的结构,也就是B树。
阶为M的B树具有以下性质:

1、根节点在不为叶子节点的情况下儿子数为 2 ~ M
2、除根结点以外的非叶子结点的儿子数为 M/2(向上取整) ~ M
3、拥有 K 个孩子的非叶子节点包含 k-1 个keys(关键字),且递增排列
4、所有叶子结点在同一层,即深度相同

(叶节点可以看成是一种外部节点,不包含任何关键字信息)
  在B-树中,每个结点中关键字从小到大排列,并且当该结点的孩子是非叶子结点时,该k-1个关键字正好是k个孩子包含的关键字的值域的分划。
因为叶子结点不包含关键字,所以可以把叶子结点看成在树里实际上并不存在外部结点,指向这些外部结点的指针为空,叶子结点的数目正好等于树中所包含的关键字总个数加1。
B树、B+树、红黑树、AVL树

B+树

B+ 树通常用于数据库和操作系统的文件系统中。特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。B+ 树元素自底向上插入。
B+树是B-树的变体,也是一种多路搜索树,其定义基本与B-树相同,不同如下:

1、拥有 K 个孩子的非叶子节点包含 k 个keys(关键字),且递增排列。每个关键字不保存数据,只用来索引。
2、所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
3、所有的非叶子结点可以看成是索引部分,结点中仅含有其子树(根结点)中最大(或最小)关键字
4、非叶子结点的子树指针P[i],指向关键字值属于[ K[i], K[i+1] )的子树
5、为所有叶子结点增加一个链指针

B树、B+树、红黑树、AVL树

红黑树

一棵二叉树如果满足下面的红黑性质,则为一棵红黑树:

1、每个结点或是红的,或是黑的。
2、根结点是黑的。
3、每个叶结点 (NIL) 是黑的。
4、如果一个结点是红的,则它的两个儿子都是黑的。
5、对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点。

B树、B+树、红黑树、AVL树

AVL树

关于AVL树,可以借鉴《数据结构——AVL树》,可以直接看这里,就不再熬诉。
定义:
1、左子树和右子树都是AVL树
2、左子树和右子树的高度差不超过1 ,|HL-HR|<=1
性质:

1、一棵n个结点的AVL树的其高度保持在0(log2(n)),不会超过3/2log2(n+1)
2、一棵n个结点的AVL树的平均搜索长度保持在0(log2(n)).
3、一棵n个结点的AVL树删除一个结点做平衡化旋转所需要的时间为0(log2(n)).

B树和B+树的区别

B/B+树用在磁盘文件组织、数据索引和数据库索引中。其中B+树比B 树更适合实际应用中操作系统的文件索引和数据库索引,因为:
1、B+树的磁盘读写代价更低
B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B 树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。

举个例子,假设磁盘中的一个盘块容纳16bytes,而一个关键字2bytes,一个关键字具体信息指针2bytes。一棵9阶B-tree(一个结点最多8个关键字)的内部结点需要2个盘快。而B+ 树内部结点只需要1个盘快。当需要把内部结点读入内存中的时候,B 树就比B+ 树多一次盘块查找时间(在磁盘中就是盘片旋转的时间)。

2、B+-tree的查询效率更加稳定
由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

3、B树在元素遍历的时候效率较低
B+树只要遍历叶子节点就可以实现整棵树的遍历。在数据库中基于范围的查询相对频繁,所以此时B+树优于B树。

红黑树的应用及和B树区别

应用:

1、广泛用在C++的STL中。map和set都是用红黑树实现的。
2、著名的linux进程调度Completely Fair Scheduler,用红黑树管理进程控制块
3、epoll在内核中的实现,用红黑树管理事件块
4、nginx中,用红黑树管理timer等
5、Java的TreeMap实现
等等

和B树比较
一言而知就是树的深度较高,在磁盘I/O方面的表现不如B树。
要获取磁盘上数据,必须先通过磁盘移动臂移动到数据所在的柱面,然后找到指定盘面,接着旋转盘面找到数据所在的磁道,最后对数据进行读写。磁盘IO代价主要花费在查找所需的柱面上,树的深度过大会造成磁盘IO频繁读写。根据磁盘查找存取的次数往往由树的高度所决定。
所以,在大规模数据存储的时候,红黑树往往出现由于树的深度过大而造成磁盘IO读写过于频繁,进而导致效率低下。在这方面,B树表现相对优异,B树可以有多个子女,从几十到上千,可以降低树的高度。

AVL树和红黑树

红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高。

1、红黑树和AVL树都能够以O(log2 n)的时间复杂度进行搜索、插入、删除操作。
2、由于设计,红黑树的任何不平衡都会在三次旋转之内解决。AVL树增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。

查找方面:
红黑树的性质(最长路径长度不超过最短路径长度的2倍),其查找代价基本维持在O(logN)左右,但在最差情况下(最长路径是最短路径的2倍少1),比AVL要略逊色一点。
AVL是严格平衡的二叉查找树(平衡因子不超过1)。查找过程中不会出现最差情况的单支树。因此查找效率最好,最坏情况都是O(logN)数量级的。

所以,综上:
AVL比RBtree更加平衡,但是AVL的插入和删除会带来大量的旋转。 所以如果插入和删除比较多的情况,应该使用RBtree, 如果查询操作比较多,应该使用AVL

AVL是一种高度平衡的二叉树,维护这种高度平衡所付出的代价比从中获得的效率收益还大,故而实际的应用不多,更多的地方是用追求局部而不是非常严格整体平衡的红黑树。当然,如果场景中对插入删除不频繁,只是对查找特别有要求,AVL还是优于红黑的。

上一篇:前端相关UED团队和个人博客整理


下一篇:JS移动li行数据,点击上移下移(是位置的互换,不是top的偏移量改变)