数据结构4 - 「二叉树家族」
一 二叉查找树
特点:非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树
查找元素过程: 从根结点开始,如果查询的关键字与结点的关键字相等则命中;否则如果查询关键字比结点关键字小就进入左儿子;比结点关键字大就进入右儿子;如果左儿子或右儿子的指针为空则找不到相应的关键字;
性能:最好的搜索性能逼近二分(非叶子节点子树节点平衡),最坏的性能是线性的,参看下图
优点:在基本平衡的情况下,二叉树比连续内存空间的二分查找的优点是,改变B树结构(插入与删除结点)不需要移动大段的内存数据,甚至通常是常数开销
衍生场景: AVL树是自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下都是O(log n)。增加和删除可能需要通过一次或多次树旋转来重新平衡
二 B-树
⚠️B树和B-树是同一种树,只不过英语中B-tree被中国人翻译成了B-树,让人以为B树和B-树是两种树,实际上,两者就是同一种树
查找过程:B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为空,或已经是叶子结点;
特点: (1) 非叶子结点的子树指针+1 = 关键字个数 (2)关键字集合分布在整颗树中 (3) 搜索有可能在非叶子结点结束
三 B+树
特点: (1) 非叶子结点的子树指针与关键字个数相同 (2) 所有关键字都在叶子结点出现 (3) 不可能在非叶子结点命中并结束。非叶子结点相当于是叶子结点的索引,叶子结点存储数据 (4) 更适合文件索引系统
(5) 叶子节点增加指向相邻叶子节点的指针,提高区间访问的性能
![](https://images2017.cnblogs.com/blog/679616/201801/679616-20180112170355113-1637410169.jpg)
四 红黑树
红黑树是一种自平衡二叉查找树,通过在插入和删除节点时进行颜色变换和旋转操作,使得树始终保持平衡状态,它具有以下特点:
- 每个节点非红即黑;
- 根节点总是黑色的;
- 每个叶子节点都是黑色的空节点(NIL 节点);
- 如果节点是红色的,则它的子节点必须是黑色的(反之不一定);
- 从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。
总结:根黑叶黑,红不相邻,黑色平衡。
和 AVL 树不同的是,红黑树并不追求严格的平衡,而是大致的平衡。正因如此,红黑树的查询效率稍有下降,因为红黑树的平衡性相对较弱,可能会导致树的高度较高,这可能会导致一些数据需要进行多次磁盘 IO 操作才能查询到,这也是 MySQL 没有选择红黑树的主要原因。也正因如此,红黑树的插入和删除操作效率大大提高了,因为红黑树在插入和删除节点时只需进行 O(1) 次数的旋转和变色操作,即可保持基本平衡状态,而不需要像 AVL 树一样进行 O(logn) 次数的旋转操作。 (查询的时间复杂度还是O(n))
红黑树的应用还是比较广泛的,TreeMap、TreeSet 以及 JDK1.8 的 HashMap 底层都用到了红黑树。对于数据在内存中的这种情况来说,红黑树的表现是非常优异的。
AVL树和红黑树区别
AVL是严格的平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多;
红黑树是用非严格的平衡来换取增删节点时候旋转次数的开销;
所以简单说,如果你的应用中,搜索的次数远远大于插入和删除,那么选择AVL树,如果搜索,插入删除次数几乎差不多,应选择红黑树。
红黑树与AVL树的调整平衡的实现机制不同,AVL靠平衡因子和旋转,红黑树靠节点颜色以及一些约定再加上旋转。因此,存在去掉颜色的红黑树不是AVL树的情况:比如左子树都是黑的,右子树都是红黑相间的,这样整个树高度2n的时候,根节点的左右层数差可以到n。