这篇博文主要想分享一下我对二叉树的思考,总结的不足的地方还请大家补充。
1、二叉搜索树(BST):
二叉搜索树是二叉树里面最基础的数据结构,也可以看作是最原始的二叉树,具体概念我就不赘述了。我认为它有以下几个特点:
- 不可控性,它的生长方向完全取决于所给的数据,极端情况下,它可能会变成只有左子树或只有右子树的链表结构。
- 树高问题,当数据量很大时,它可能会长得很高,这样会使查询变得特别慢。
- 磁盘IO问题,因为它的每个节点只存储一个数据,这样,当涉及大量数据查询时,将会引发巨大的IO,可能导致查询故障。
- 插入数据问题,在大数据量下,当向二叉搜索树插入一个大的有序文件,所引发的问题将会是灾难性的,因为这个文件内的所有记录都要向后移一个位置。
- 值得一提的是,二叉搜索树的时间复杂度很大程度上取决于IO的大小,即树的高度。一般的,树高为log(n) ,因此时间复杂度一般为O(log(n))。
额外提一下:时间复杂度O(f(n))是指某个算法在执行时所消费的时间与数据的增长量之间的函数关系,其中的f(n)即就是这个函数。时间复杂度用O表示,同理也可以得知空间复杂度和算法复杂度。对于上述的O(log(n)),我们可以得知,它描述的是此算法的时间复杂度为O(log(n)),其中,n为输入数据的量(因为时间复杂度描述的是当输入趋于无穷大时,T(n)/f(n)的极限的取值情况)。
2、二叉平衡树(AVL):
二叉平衡树可以看作是对二叉搜索树的改进优化。它要求左右子树深度之差的绝对值不超过1,此外,左右子树也要分别是二叉平衡树。这就有效的平衡了二叉搜索树的不可控性,使树不至于长得太高,这样,IO就会有效的被减小,从而使查询变得很快。我们知道,当向二叉平衡树中插入或删除数据时,往往会破环二叉平衡树的平衡,所以此时就需要进行旋转调节使其恢复平衡。失衡类型主要有LL,LR,RR,RL四种类型。具体的调节可以参照如下视频中的旋转动图:二叉树通过旋转来调节失衡的动图。
3、红黑树(RBT):
红黑树是不严格的二叉平衡树,或者说是变种的二叉平衡树,红黑树试图用颜色来重新定义二叉平衡树,或者又可以说它就是二叉平衡树的优化改进。同样,这里我也就不详细的说概念了。我自己觉得有关红黑树比较重要的几点是:
- 插入的结点必须是红色的
- 若子节点是黑色,则它的子节点既可以是红色也可以是黑色
- 红节点的孩子节点必须是黑色
- 从根到任意叶子节点的路径上,黑结点数目一样多
- 从根结点到叶子节点的最长路径不多于最短路径的两倍
- 对于红黑树,插入,删除和查找的时间复杂度都是O(log(n))
- 每个叶节点(NIL节点,空节点)是黑色的
- 红黑树不是高度平衡的,对于红黑树,插入最多两次旋转,删除最多三次旋转。旋转的具体实现可参考结点调节旋转动图
- 红黑树同样也是弱平衡的,为了维持它的数据结构特性,红黑树通常用非严格的平衡换取增删结点时旋转次数的减少
- 值得注意的是,若是搜索的次数大大多于插入和删除,那么推荐使用二叉平衡树(AVL树),因为它优秀的平衡性能使查询变得很快;若是搜索的次数和插入,删除相差不多,那么建议使用红黑树,它会有更出色表现。这是因为,红黑树本来就是二叉平衡树的改进,所以它的搜索性能较为强劲,再加上红黑树的各种特性,也使它的插入删除性能得到提升,所以,红黑树在这样方面表现得很抢眼。
4、B树(B-树):
B树就是比二叉树长得更茂密的一种树。所以B树不再是两个叉,而是多个叉,它的茂密之处还在于它的叶子结点和非叶子结点都存储数据。而且,叶子结点不存储关键字,这样,采用中序遍历就可以访问所有数据。对于B树,我认为,由于是“多叉的”,所以,它的树高肯定会降低,再者,每个结点上都存储数据,因此,磁盘IO就会被大大的降低,这将有利于提高效率。
5、B+树:
B+树是在B树上做了优化,具体如下:
- 它不再是非叶子结点,叶子结点都存储数据,而是变成了只在同一层的叶子结点上存储数据
- 在众多的非叶子结点上,B+树存储相应的索引key,这样,大量的结点就会被用来存储索引,这将有效的提高存储能力,并将大大加快查询的效率,此外,数据的存储相对比较紧密,这也非常适合大数据量的磁盘存储
- B+树区别于B树的还有它在各个叶子上加了链表,这样获取所有结点就不再需要中序遍历
- 需要指出的是,基于以上特性,B+树更适合做范围查找
总说:以上所说的数据结构都有各自的特点,但笼统地说,就大数据量应用,B+树是这几个里面表现最好的。