关于几个平衡搜索树的深入探讨
=========================

## Splay树

> Splay树基本操作的分摊时间复杂度为`O(logn)`，如何证明这个结论？

## AVL树

> 高度为h的AVL树，至少拥有`fib(h + 3) - 1`个节点，此时对应了一棵`fib-AVL`数。

可以归纳地证明该结论。

> 对于任意一棵高度为h的AVL树，其叶节点的高度深度为$\lceil \frac{h}{2} \rceil$。

可以归纳地证明该结论。

> 对于一棵高度为h的AVL树进行删除，至多只会有一个节点失衡，但是至多需要进行`O(h) = O(logn)`次调整。具体说来，至多需要$\lfloor \frac{h}{2} \rfloor$次调整操作。

可以构造一棵高度为`h`的`fib-AVL`树，删除它的最左侧节点。当`h`为偶数时，该节点是叶节点，作为深度最低的一个节点，它的深度恰好是`AVL`树的深度下界，即$\lceil \frac{h}{2} \rceil = \frac{h}{2}$，对它进行删除后，该节点的所有祖先节点都需要一次调整，故一共需要$\frac{h}{2}$次调整操作。

当`h`为奇数时，最左侧节点`m`并非叶节点，它拥有一个右孩子，该右孩子是深度最低的叶节点。因此`m`的深度为$\lceil \frac{h}{2} \rceil - 1 = \lfloor \frac{h}{2} \rfloor$。将`m`删除，其实质是删除它的右孩子，这将导致`m`的所有祖先节点都进行一次调整操作，故一共需要$\lfloor \frac{h}{2} \rfloor$次调整。

综上，删除操作后最多进行的调整次数为$\lfloor \frac{h}{2} \rfloor$。

需要注意的是这里说的是调整操作，而不是旋转操作。在`fib-AVL`树中，每次这样的调整都可以通过单旋来完成。但是，可以通过对`fib-AVL`树的结构做简单的改变，使得这样的调整需要双旋来完成。这样，总体的旋转次数为$2 \cdot \lfloor \frac{h}{2} \rfloor$次。

> 证明：按照递增次序，将$2^{h + 1} - 1$个关键码依次插入到一棵初始为空的`AVL`树中，必然得到高度为`h`的一棵满二叉树。

下面归纳地证明该结论。

+ 当`h = 0`时，结论显然成立。
+ 假设对于任意高度不大于`h`的`AVL`树，该结论都是成立的。
+ 下面讨论将$2^{h + 2} - 1$个节点以递增次序插入到一棵初始为空的`AVL`树的过程。

	- 首先插入前$[0, 2^{h + 1} - 1)$个关键码。根据归纳假设，此时将形成一棵高度为`h`的`AVL`树。
	- 然后插入$[2^{h + 1} - 1， 3\cdot 2^{h} - 1)$的关键码。这些关键码将全部被插入到右子树中，而对左子树没有任何影响。根据归纳假设，此时右子树形成了一棵高度为`h`的`AVL`树，因此全树的高度为`h + 1`。
	- 插入第$3\cdot 2^{h} - 1$个关键码。此时在根节点不满足`AVL`树的平衡条件，因此需要做一次单旋调整。调整以后，左子树成为一棵高度为`h`的满二叉树，右子树的高度也为`h`，但是在最底层只有一个关键码，即刚刚插入的关键码。
	- 继续插入$[3\cdot 2^{h} - 1, 2^{h + 2} - 1)$个关键码，同样，这些关键码将被插入到右子树，而与左子树无关。根据归纳假设，插入完成后，右子树成为了一棵高度为`h`的满二叉树，此时全树也就成为了一棵高度为`h + 1`的满二叉树。
证毕。

实际上，可以类似地证明，将$2^{h + 1} - 1$个关键码以递减次序，依次插入到一棵初始为空的`AVL`树中，也可以得到一棵高度为`h`的满二叉树。

## B树


