--------------------------------------------------------------------------------
标题: 关于平衡二叉树(AVL tree)旋转后平衡标志调整的计算公式
作者: 叶飞虎
建立: 2009.10.18
变更: 2010.06.22
--------------------------------------------------------------------------------
1. 引言
平衡二叉树的平衡标志计算可以说是最简单的, 也可以说是AVL树中最难的。平衡标
志计算方法有两种:
a. Balance = Height(Left) - Height(Right);
b. Balance = Height(Right) - Height(Left);
其中 Height 为结点的子树高度(>= 0), 算法简单就是说只要左右子树高度相减即可,
但运行效率不高。当结点数上千以上时, 频繁增删结点带来开销会相当可观, 正因如此,
本人通过推理得到的计算公式就非常重要了。
2. 假设
a. 结点定义
typedef struct TAVLNode
{
void* Item; // 存放项
TAVLNode* Left; // 左子结点
TAVLNode* Right; // 右子结点
TAVLNode* Parent; // 父结点
char Balance; // 平衡标志: [-1..1]
} *PAVLNode;
b. 平衡增量 D 和 D', D 为左子树增量, D' 为右子树增量, 且 D = -D', D 可以定义
为 1 或 -1, 其中:
1). D = 1 则表示平衡标志计算方法为: Height(Left) - Height(Right)
2). D = -1 则表示平衡标志计算方法为: Height(Right) - Height(Left)
c. 结点高度的函数 H, 则结点 n 有:
H(n) = M(H(n.Left), H(n.Right)) + D, 同时 H(NULL) = 0
其中, M(H(n.Left), H(n.Right) 函数描述如下:
1). |H(n.Left)| >= |H(n.Right)| 则值为: H(n.Left)
2). |H(n.Left)| < |H(n.Right)| 则值为: H(n.Right)
d. 结点平衡标志的函数 B, 则结点 n 有:
B(n) = n.Balance = H(n.Left) - H(n.Right)
3. 旋转方式(Left-Left)
a. 旋转前的树结构和函数方程如下:
(p) B(p) = H(t) - H(1) = 2D
/ \
(t) (1) B(t) = H(n) - H(2)
/ \
(n) (2) B(n) = H(3) - H(4)
/ \
(3) (4) 同时必定存在: B(t) != D', 可以用反证法证明.
b. 旋转后的树结构和函数方程如下: (注: 结点 p, t, n 旋转后分别定义为 P, T, N)
( T ) B(T) = H(N) - H(P)
/ \ B(N) = H(3) - H(4)
(N) (P) B(P) = H(2) - H(1)
/ \ / \
(3) (4) (2)(1) 同时必定存在: B(P) != D', 可以用反证法证明.
c. B(N) 公式
B(N) = H(3) - H(4) \
B(n) = H(3) - H(4) / => B(N) = B(n) = n.Balance
d. B(P) 公式
B(t) = H(n) - H(2) => H(2) = H(n) - B(t) -+
B(p) = H(t) - H(1) = 2D => H(1) = H(t) - 2D +
B(P) = H(2) - H(1) -