自平衡二叉搜索树
自平衡二叉搜索树可以自动调节节点的位置,以保证树的深度始终是最小值。树的深度是指根节点到最深叶节点的距离。保证深度足够小可以让树的各种操作效率变高。但二叉搜索树保持自平衡会产生较大的时间开销。
实现自平衡树的两种著名数据结构是红黑树和AVL树。
红黑树(RBT)
AVL是严格平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多;
红黑树是弱平衡的,用非严格的平衡来换取增删节点时候旋转次数的降低;
红黑树上每个结点内含五个域,color,key,left,right,p。如果相应的指针域没有,则设为NIL。
一般的,红黑树,满足以下性质,即只有满足以下全部性质的树,我们才称之为红黑树:
1)每个结点要么是红的,要么是黑的。
2)根结点是黑的。
3)每个叶结点,即空结点(NIL)是黑的。
4)如果一个结点是红的,那么它的俩个儿子都是黑的。
5)对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点。
红黑树并不追求“完全平衡”——它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能。
红黑树进行搜索、插入、删除的时间复杂度均为O(log2 n)。 !!!!!!!!!!
此外,由于它的设计,任何不平衡都会在3次旋转之内解决。当然,还有一些更好的,但实现起来更复杂的数据结构,能够做到一步旋转之内达到平衡,但红黑树能够给我们一个比较“便宜”的解决方案。红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高。
当然,红黑树并不适应所有应用树的领域。如果数据基本上是静态的,那么让他们待在他们能够插入,并且不影响平衡的地方会具有更好的性能。如果数据完全是静态的,做一个哈希表,性能可能会更好一些。
红黑树是一个更高效的检索二叉树,因此常常用来实现关联数组。典型地,JDK 提供的集合类 TreeMap 本身就是一个红黑树的实现。
AVL树
AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个儿子子树的高度最大差别为一,所以它也被称为高度平衡树。
查找、插入和删除在平均和最坏情况下都是O(logn)。!!!!
增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。
AVL树的定义:一棵AVL树满足以下的条件:
1、它的左子树和右子树都是AVL树
2、左子树和右子树的高度差不能超过1
性质:
1、一棵n个结点的AVL树的其高度保持在0(log2(n)),不会超过
3/2log2(n+1)
2、一棵n个结点的AVL树的平均搜索长度保持在0(log2(n)).
3、一棵n个结点的AVL树删除一个结点做平衡化旋转所需要的时间为
0(log2(n)).
为了保证平衡,AVL树中的每个结点都有一个平衡因子(balance factor,以下用BF表示),它表示这个结点的左、右子树的高度差,也就是左子树的高度减去右子树的高度的结果值。AVL树上所有结点的BF值只能是-1、0、1。反之,只要二叉树上一个结点的BF的绝对值大于1,则该二叉树就不是平衡二叉树。
例题:
1、关于红黑树和AVL树,以下哪种说法不正确?
正确答案:D
A、两者都属于自平衡二叉树
B、两者查找,插入,删除的时间复杂度相同
C、包含n个内部节点的红黑树的高度是O(log(n))
D、JDK的TreeMap是一个AVL的实现