平衡搜索树
完整可编译运行代码见:Github::Data-Structures-Algorithms-and-Applications/_34Balanced search tree
概述
本章会讲AVL、红-黑树、分裂树、B-树。
平衡搜索树的应用?
AVL 和红-黑树和分裂树适合内部存储的应用。
B-树适合外部存储的应用,例如,存储在磁盘上的大型词典。
STL类map 和 multimap使用的是红-黑树结构,以保证查找、插入和删除操作具有对数级的时间性能。
什么时候适合用平衡搜索树?
- 按关键字实施字典操作,而且操作时间不能超过指定的范围。
- 按名次实施的查找和删除操作。
- 不按精确的关键字匹配所进行的字典操作(例如寻找关键字大于k的最小元素)。
AVL和红-黑树的旋转?
AVL树对每个插人操作最多需要一次旋转,对每个删除操作最多需要O(logn)次旋转。
红-黑树对每个插入和删除操作,都只需要一次旋转。
当一次旋转只需用时 Θ ( 1 ) \Theta(1) Θ(1)时,他们之间的区别不明显。但是当一次旋转的时间复杂度比较高时,比如平衡优先搜索树。平衡优先搜索树用于描述具有二维关键字的元素,此时,每个关键字是一数对(x,y)。它是关于y的优先队列,同时又是关于x的搜索树。在这样的树中,每一次旋转都需耗时 O(logn)。如果用红-黑树来描述平衡优先搜索树,则因为每一次插入或删除仅需要执行一次旋转,所以插入或删除操作的总时间仍保持为O(logn)。当使用AVL树时,则删除操作的时间将变为 O ( l o g 2 n ) O(log^2n) O(log2n)。
AVL树
定义
如果搜索树的高度总是O(logn),我们就能保证查找、插人和删除的时间为O(logn)。最坏情况下的高度为O(logn)的树称为平衡树(balanced tree)。比较流行的一种平衡树是AVL树(AVL tree),它是Adelson-Velskii 和 Landis在 1962年提出的。
定义15-1一棵空的二叉树是AVL树;如果T是一棵非空的二叉树, T L T_L TL和 T R T_R TR分别是其左子树和右子树,那么当T满足以下条件时,T是一棵AVL树:
1) T L T_L TL和 T R T_R TR是AVL树;2) ∣ h L − h R ∣ < 1 |h_L-h_R|<1 ∣hL−hR∣<1,其中 h L h_L hL和 h R h_R hR分别是 T L T_L TL和 T R T_R TR的高。
一棵AVL搜索树既是二叉搜索树,也是AVL树。
一棵索引AVL搜索树既是索引二叉搜索树,也是AVL树。
用AVL搜索树来描述字典的要求
如果用AVL搜索树来描述字典,并在对数级时间内完成每一种字典操作,那么,我们必须确定AVL树的下述特征:
1)一棵n个元素的AVL树,其高度是O(logn)。
2)对于每一个n, n ≥ 0 n\geq 0 n≥0,都存在一棵AVL树。
3)对一棵n元素的AVL搜索树,在O(高度)=O(logn)的时间内可以实现查找。
4)将一个新元素插入一棵n元素的AVL搜索树中,可以得到一棵n+1个元素的AVL树,而且插人用时为O(logn)。
5)一个元素从一棵n元素的AVL搜索树中删除,可以得到一棵n-1个元素的AVL树,而且删除用时为O(logn)。
AVL树的高度
对一棵高度为h的AVL树,令 N h N_h Nh是其最少的节点数。在最坏情况下,根的一棵子树的高度是h-1,另一棵子树的高度是h-2,而且两棵子树都是AVL树。因此有:
N h = N h − 1 + N h − 2 + 1 , N 0 = 0 且 N 1 = 1 N_h=N_{h-1}+N_{h-2}+1,N_0=0且N_1=1 Nh=Nh−1+Nh−2+1,N0=0且N1=1
N h N_h Nh的定义与斐波拉契数列的定义是相似的:
F n = F n − 1 + F n − 2 , F 0 = 0 且 F 1 = 1 F_n = F_{n - 1} + F_{n-2}, F_0=0且F_1 = 1 Fn=Fn−1+Fn−2,F0=0且F1=1
经分析可得 N h N_h Nh的列表为:1,2,4,7,12,20,33…
F n F_n Fn的列表为:1,1,2,3,5,8,13,21,34…
因此 N h N_h Nh可以表示为:
N h = F h + 2 − 1 , h ≥ 0 N_h=F_{h+2}-1,h\geq 0 Nh=Fh+2−1,h≥0
由斐波拉契定理可知:
F h = ϕ h 5 F_h=\frac{\phi^h}{\sqrt{5}} Fh=5