形态匀称的二叉树称为平衡二叉树 (Balanced binary tree) ,其严格定义是:
一棵空树是平衡二叉树;若 T 是一棵非空二叉树,其左、右子树为 TL 和 TR ,令 hl 和 hr 分别为左、右子树的深度。当且仅当
①TL 、 TR 都是平衡二叉树;
② | hl - hr |≤ 1;
时,则 T 是平衡二叉树。
【例】如图 8.4 所示。
(a)平衡二叉树 (b)非平衡二叉树
图8.3 平衡二叉树与非平衡二叉树
相应地定义 hl - hr 为二叉平衡树的平衡因子 (balance factor) 。因此,平衡二叉树上所有结点的平衡因子可能是 -1 , 0 , 1 。换言之,若一棵二叉树上任一结点的平衡因子的绝对值都不大于 1 ,则该树是就平衡二叉树。
动态平衡技术
1.动态平衡技术
Adelson-Velskii 和 Landis 提出了一个动态地保持二叉排序树平衡的方法,其基本思想是:
在构造二叉排序树的过程中,每当插入一个结点时,首先检查是否因插入而破坏了树的平衡性,如果是因插入结点而破坏了树的平衡性,则找出其中 最小不平衡子树,在保持排序树特性的前提下,调整最小不平衡子树中各结点之间的连接关系,以达到新的平衡。通常将这样得到的平衡二叉排序树简称为 AVL 树。
2.最小不平衡子树
以离插入结点最近、且平衡因子绝对值大于 1 的结点作根结点的子树。为了简化讨论,不妨假设二叉排序树的最小不平衡子树的根结点为 A ,则调整该子树的规律可归纳为下列四种情况:
(1) LL 型:
新结点 X 插在 A 的左孩子的左子树里。调整方法见图 8.5(a) 。图中以 B 为轴心,将 A 结点从 B 的右上方转到 B 的右下侧,使 A 成为 B 的右孩子。
图8.5 平衡调整的4种基本类型(结点旁的数字是平衡因子)
(2)RR 型:
新结点 X 插在 A 的右孩子的右子树里。调整方法见图 8.5(b) 。图中以 B 为轴心,将 A 结点从 B 的左上方转到 B 的左下侧,使 A 成为 B 的左孩子。
(3)LR 型:
新结点 X 插在 A 的左孩子的右子树里。调整方法见图 8.5(c) 。分为两步进行:第一步以 X 为轴心,将 B 从 X 的左上方转到 X 的左下侧,使 B 成为 X 的左孩子, X 成为 A 的左孩子。第二步跟 LL 型一样处理 ( 应以 X 为轴心 ) 。
(4)RL 型:
新结点 X 插在 A 的右孩子的左子树里。调整方法见图 8.5(d) 。分为两步进行:第一步以 X 为轴心,将 B 从 X 的右上方转到 X 的右下侧,使 B 成为 X 的右孩子, X 成为 A 的右孩子。第二步跟 RR 型一样处理 ( 应以 X 为轴心 ) 。
【例】
实际的插入情况,可能比图 8.5 要复杂。因为 A 、 B 结点可能还会有子树。现举一例说明,设一组记录的关键字按以下次序进行插入: 4 、 5 、 7 , 2 、 1 、 3 、 6 ,其生成及调整成二叉平衡树的过程示于图 8.6 。
在图 8.6 中,当插入关键字为 3 的结点后,由于离结点 3 最近的平衡因子为 2 的祖先是根结点 5 。所以,第一次旋转应以结点 4 为轴心,把结点 2 从结点 4 的左上方转到左下侧,从而结点 5 的左孩子是结点 4 ,结点 4 的左孩子是结点 2 ,原结点 4 的左孩子变成了结点 2 的右孩子。第二步再以结点 4 为轴心,按 LL 类型进行转换。这种插入与调整平衡的方法可以编成算法和程序,这里就不再讨论了。
图 8.6 二叉平衡树插入结点 ( 结点旁的数字为其平衡因子 )
一棵空树是平衡二叉树;若 T 是一棵非空二叉树,其左、右子树为 TL 和 TR ,令 hl 和 hr 分别为左、右子树的深度。当且仅当
①TL 、 TR 都是平衡二叉树;
② | hl - hr |≤ 1;
时,则 T 是平衡二叉树。
【例】如图 8.4 所示。
(a)平衡二叉树 (b)非平衡二叉树
图8.3 平衡二叉树与非平衡二叉树
相应地定义 hl - hr 为二叉平衡树的平衡因子 (balance factor) 。因此,平衡二叉树上所有结点的平衡因子可能是 -1 , 0 , 1 。换言之,若一棵二叉树上任一结点的平衡因子的绝对值都不大于 1 ,则该树是就平衡二叉树。
动态平衡技术
1.动态平衡技术
Adelson-Velskii 和 Landis 提出了一个动态地保持二叉排序树平衡的方法,其基本思想是:
在构造二叉排序树的过程中,每当插入一个结点时,首先检查是否因插入而破坏了树的平衡性,如果是因插入结点而破坏了树的平衡性,则找出其中 最小不平衡子树,在保持排序树特性的前提下,调整最小不平衡子树中各结点之间的连接关系,以达到新的平衡。通常将这样得到的平衡二叉排序树简称为 AVL 树。
2.最小不平衡子树
以离插入结点最近、且平衡因子绝对值大于 1 的结点作根结点的子树。为了简化讨论,不妨假设二叉排序树的最小不平衡子树的根结点为 A ,则调整该子树的规律可归纳为下列四种情况:
(1) LL 型:
新结点 X 插在 A 的左孩子的左子树里。调整方法见图 8.5(a) 。图中以 B 为轴心,将 A 结点从 B 的右上方转到 B 的右下侧,使 A 成为 B 的右孩子。
图8.5 平衡调整的4种基本类型(结点旁的数字是平衡因子)
(2)RR 型:
新结点 X 插在 A 的右孩子的右子树里。调整方法见图 8.5(b) 。图中以 B 为轴心,将 A 结点从 B 的左上方转到 B 的左下侧,使 A 成为 B 的左孩子。
(3)LR 型:
新结点 X 插在 A 的左孩子的右子树里。调整方法见图 8.5(c) 。分为两步进行:第一步以 X 为轴心,将 B 从 X 的左上方转到 X 的左下侧,使 B 成为 X 的左孩子, X 成为 A 的左孩子。第二步跟 LL 型一样处理 ( 应以 X 为轴心 ) 。
(4)RL 型:
新结点 X 插在 A 的右孩子的左子树里。调整方法见图 8.5(d) 。分为两步进行:第一步以 X 为轴心,将 B 从 X 的右上方转到 X 的右下侧,使 B 成为 X 的右孩子, X 成为 A 的右孩子。第二步跟 RR 型一样处理 ( 应以 X 为轴心 ) 。
【例】
实际的插入情况,可能比图 8.5 要复杂。因为 A 、 B 结点可能还会有子树。现举一例说明,设一组记录的关键字按以下次序进行插入: 4 、 5 、 7 , 2 、 1 、 3 、 6 ,其生成及调整成二叉平衡树的过程示于图 8.6 。
在图 8.6 中,当插入关键字为 3 的结点后,由于离结点 3 最近的平衡因子为 2 的祖先是根结点 5 。所以,第一次旋转应以结点 4 为轴心,把结点 2 从结点 4 的左上方转到左下侧,从而结点 5 的左孩子是结点 4 ,结点 4 的左孩子是结点 2 ,原结点 4 的左孩子变成了结点 2 的右孩子。第二步再以结点 4 为轴心,按 LL 类型进行转换。这种插入与调整平衡的方法可以编成算法和程序,这里就不再讨论了。
图 8.6 二叉平衡树插入结点 ( 结点旁的数字为其平衡因子 )
代码:
template<class E, class K>
class AVLtree
{
public:
AVLtree() {root = 0;}
~AVLtree() {Erase(root);}
bool Search(const K& k, E& e) const;
AVLtree<E,K>& Insert(const E& e);
AVLtree<E,K>& Delete(const K& k, E& e);
void Ascend() {InOutput(root); cout << endl;}
void PostOut() {PostOutput(root); cout << endl;}
private:
AVLNode<E,K> *root;
void Erase(AVLNode<E,K> *t);
void InOutput(AVLNode<E,K> *t);
void PostOutput(AVLNode<E,K> *t);
void FixBF(AVLNode<E,K> *, AVLNode<E,K>*, const E&);
void RRrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);
void LLrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);
void RLrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);
void LRrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);
};
template<class E, class K>
void AVLtree<E,K>::Erase(AVLNode<E,K> *t)
{
//用前序遍历的方式删除所有节点
if (t)
{
Erase(t->LeftChild);
Erase(t->RightChild);
delete t;
}
}
template<class E, class K>
bool AVLtree<E,K>::Search(const K& k, E &e) const
{
AVLNode<E,K> *p = root;
while (p)
{
if (k < p->data)
p = p->LeftChild;
else if (k > p->data)
p = p->RightChild;
else
{
e = p->data;
return true;
}
}
return false;
}
template<class E, class K>
void AVLtree<E,K>::FixBF(AVLNode<E,K> *q,
AVLNode<E,K> *r, const E &e)
{
//从q到r的平衡因子通常为0
//根据实际情况改变成 +1 或 -1
while (q != r)
{
if (e < q->data)
{
q->bf = 1;
q = q->LeftChild;
}
else
{
q->bf = -1;
q = q->RightChild;
}
}
}
template<class E, class K>
void AVLtree<E,K>::LLrotate(AVLNode<E,K> *PA, AVLNode<E,K> *A, AVLNode<E,K> *B)
{
//LL型的旋转
A->LeftChild = B->RightChild;
B->RightChild = A;
if (PA) // A 是否有父节点
{
if (A == PA->LeftChild)
PA->LeftChild = B;
else
PA->RightChild = B;
}
else
{
root = B;
}
//设置平衡因子
A->bf = B->bf = 0;
}
template<class E, class K>
void AVLtree<E,K>::RRrotate(AVLNode<E,K> *PA, AVLNode<E,K> *A, AVLNode<E,K> *B)
{
//RR型的旋转
A->RightChild = B->LeftChild;
B->LeftChild = A;
if (PA) // A 是否有父节点
{
if (A == PA->LeftChild)
PA->LeftChild = B;
else
PA->RightChild = B;
}
else
{
root = B;
}
//设置平衡因子
A->bf = B->bf = 0;
}
template<class E, class K>
void AVLtree<E,K>::LRrotate(AVLNode<E,K> *PA,
AVLNode<E,K> *A, AVLNode<E,K> *B)
{
//LR型的旋转
AVLNode<E,K> *C = B->RightChild;
A->LeftChild = C->RightChild;
B->RightChild = C->LeftChild;
C->LeftChild = B;
C->RightChild = A;
if (PA) // A 是否有父节点
{
if (A == PA->LeftChild)
PA->LeftChild = C;
else
PA->RightChild = C;
}
else
{
root = C;
}
//设置平衡因子
int b = C->bf;
if (b == 1)
{
B->bf = 0;
A->bf = -1;
}
else if (b == -1)
{
B->bf = 1;
A->bf = 0;
}
else // b = 0
{
B->bf = A->bf = 0;
}
C->bf = 0;
}
template<class E, class K>
void AVLtree<E,K>::RLrotate(AVLNode<E,K> *PA,
AVLNode<E,K> *A, AVLNode<E,K> *B)
{
//RL型的旋转
AVLNode<E,K> *C = B->LeftChild;
A->RightChild = C->LeftChild;
B->LeftChild = C->RightChild;
C->LeftChild = A;
C->RightChild = B;
if (PA) // A 是否有父节点
{
if (A == PA->LeftChild)
PA->LeftChild = C;
else
PA->RightChild = C;
}
else
{
root = C;
}
//设置平衡因子
int b = C->bf;
if (b == 1)
{
B->bf = -1;
A->bf = 0;
}
else if (b == -1)
{
B->bf = 0;
A->bf = 1;
}
else // b = 0
{
B->bf = A->bf = 0;
}
C->bf = 0;
}
template<class E, class K>
AVLtree<E,K>& AVLtree<E,K>::Insert(const E& e)
{
AVLNode<E,K> *p = root,
*pp = 0, // p的父节点
*A = 0, // 平衡因子不为0 的最后一个节点
*PA; // A的父节点
//找到可以插入的地方
//同时记录最后一个平衡因子不为0的节点及其父节点
while (p)
{
if (p->bf)
{
A = p;
PA = pp;
}
pp = p;
// 将p移向子节点
if (e < p->data)
p = p->LeftChild;
else if (e > p->data)
p = p->RightChild;
else
throw BadInput();
/*if(e <= p->data)
p = p->LeftChild;
else
p = p->RightChild;*/
}
AVLNode<E,K> *r = new AVLNode<E,K> (e);
if (root)
{
if (e < pp->data)
pp->LeftChild = r;
else
pp->RightChild = r;
}
else
{
root = r;
return *this;
}
//查看是否需要再平衡,还是只是简单的刷新下平衡因子
if(A)
{
if (A->bf < 0) // bf = -1 在插入前
{
if (e < A->data)
{
//插入到A的左子树,左子树高度加1
//A新的平衡因子等于0, 不需要再平衡
A->bf = 0;
//刷新下从A到r的平衡因子
FixBF(A->LeftChild,r,e);
}
else
{
//插入到A的右子树
//A的平衡因子为-2, 需要再平衡
AVLNode<E,K> *B = A->RightChild;
if (e > B->data)
{
// RR型
FixBF(B->RightChild,r,e);
RRrotate(PA,A,B);
}
else
{
// RL型
FixBF(B->LeftChild,r,e);
RLrotate(PA,A,B);
}
}
}
else // bf = +1 在插入前
{
if (e > A->data)
{
//插入到A的右子树,右子树高度加1
//A新的平衡因子等于0, 不需要再平衡
A->bf = 0;
//刷新下从A到r的平衡因子
FixBF(A->RightChild,r,e);
}
else
{
//插入到A的左子树
//A的平衡因子为+2, 需要再平衡
AVLNode<E,K> *B = A->LeftChild;
if (e < B->data)
{
// LL型
FixBF(B->LeftChild,r,e);
LLrotate(PA,A,B);
}
else
{
// LR型
FixBF(B->RightChild,r,e);
LRrotate(PA,A,B);
}
}
}
}
else // A一直为0, 不需要再平衡
{
//刷新下从root到r的平衡因子
FixBF(root,r,e);
}
return *this;
}
template<class E, class K>
AVLtree<E,K>& AVLtree<E,K>::Delete(const K& k, E& e)
{
// 如果元素数量超过2^60, S栈将会溢出
Stack<AVLNode<E,K>*> S(100);
AVLNode<E,K> *p = root;
while (p && p->data != k)
{
S.Add(p);
if (k < p->data)
p = p->LeftChild;
else
p = p->RightChild;
}
if (!p)
throw BadInput();
e = p->data;
//p有两个子树的情况
if (p->LeftChild && p->RightChild)
{
//查找p左子树里元素值最大的节点
S.Add(p);
AVLNode<E,K> *s = p->LeftChild;
while (s->RightChild)
{
S.Add(s);
s = s->RightChild;
}
//将p左子树里元素值最大的节点等于p
p->data = s->data;
p = s;
}
//只有一个子树的情况
AVLNode<E,K> *c;
if (p->LeftChild)
c = p->LeftChild;
else
c = p->RightChild;
if (p == root)
{
root = c;
}
else
{
if (p == S.Top()->LeftChild)
S.Top()->LeftChild = c;
else
S.Top()->RightChild = c;
}
E f = p->data; //f也许不等于e
delete p;
AVLNode<E,K> *q;
try
{
S.Delete(q);
}
catch (OutOfBounds)
{
//根节点被删除了
return *this;
}
while (q)
{
if (f <= q->data)
{
//从q的左子树删除的
q->bf--;
//高度并未发生改变, 不需要再做什么
if (q->bf == -1)
return *this;
if (q->bf == -2)
{
//树变得不平衡了, 需要旋转
AVLNode<E,K> *B = q->RightChild,
*PA; // q就是A节点
// PA是A的父节点
try
{
S.Delete(PA);
}
catch (OutOfBounds)
{
//说明A是根节点
PA = 0;
}
switch (B->bf)
{
case 0: // L0型
RRrotate(PA,q,B);
B->bf = 1;
q->bf = -1;
return *this;
case 1: // L1型
RLrotate(PA,q,B);
break;
case -1:// L-1型
RRrotate(PA,q,B);
break;
}
q = PA;
}
else // q->bf == 0
{
try
{
S.Delete(q);
}
catch (OutOfBounds)
{
return *this;
}
}
}
else
{
//从q的右子树删除的
q->bf++;
//高度并未发生改变, 不需要再做什么
if (q->bf == 1)
return *this;
if (q->bf == 2)
{
//树变得不平衡了, 需要旋转
AVLNode<E,K> *B = q->LeftChild,
*PA; // q就是A节点
// PA是A的父节点
try
{
S.Delete(PA);
}
catch (OutOfBounds)
{
//说明A是根节点
PA = 0;
}
switch (B->bf)
{
case 0: // R0型
LLrotate(PA,q,B);
B->bf = -1;
q->bf = 1;
return *this;
case 1: // R1型
LLrotate(PA,q,B);
break;
case -1: // R-1 型
LRrotate(PA,q,B);
break;
}
q = PA;
}
else // q->bf == 0
{
try
{
S.Delete(q);
}
catch (OutOfBounds)
{
return *this;
}
}
}
}
return *this;
}
template<class E, class K>
void AVLtree<E,K>::InOutput(AVLNode<E,K> *t)
{
if(t)
{
InOutput(t->LeftChild);
cout << t->data << " ";
InOutput(t->RightChild);
}
}
template<class E, class K>
void AVLtree<E,K>::PostOutput(AVLNode<E,K> *t)
{
if(t)
{
PostOutput(t->LeftChild);
PostOutput(t->RightChild);
cout << t->data << " ";
}
}
template<class E, class K>
class AVLtree
{
public:
AVLtree() {root = 0;}
~AVLtree() {Erase(root);}
bool Search(const K& k, E& e) const;
AVLtree<E,K>& Insert(const E& e);
AVLtree<E,K>& Delete(const K& k, E& e);
void Ascend() {InOutput(root); cout << endl;}
void PostOut() {PostOutput(root); cout << endl;}
private:
AVLNode<E,K> *root;
void Erase(AVLNode<E,K> *t);
void InOutput(AVLNode<E,K> *t);
void PostOutput(AVLNode<E,K> *t);
void FixBF(AVLNode<E,K> *, AVLNode<E,K>*, const E&);
void RRrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);
void LLrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);
void RLrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);
void LRrotate(AVLNode<E,K> *, AVLNode<E,K>*, AVLNode<E,K> *);
};
template<class E, class K>
void AVLtree<E,K>::Erase(AVLNode<E,K> *t)
{
//用前序遍历的方式删除所有节点
if (t)
{
Erase(t->LeftChild);
Erase(t->RightChild);
delete t;
}
}
template<class E, class K>
bool AVLtree<E,K>::Search(const K& k, E &e) const
{
AVLNode<E,K> *p = root;
while (p)
{
if (k < p->data)
p = p->LeftChild;
else if (k > p->data)
p = p->RightChild;
else
{
e = p->data;
return true;
}
}
return false;
}
template<class E, class K>
void AVLtree<E,K>::FixBF(AVLNode<E,K> *q,
AVLNode<E,K> *r, const E &e)
{
//从q到r的平衡因子通常为0
//根据实际情况改变成 +1 或 -1
while (q != r)
{
if (e < q->data)
{
q->bf = 1;
q = q->LeftChild;
}
else
{
q->bf = -1;
q = q->RightChild;
}
}
}
template<class E, class K>
void AVLtree<E,K>::LLrotate(AVLNode<E,K> *PA, AVLNode<E,K> *A, AVLNode<E,K> *B)
{
//LL型的旋转
A->LeftChild = B->RightChild;
B->RightChild = A;
if (PA) // A 是否有父节点
{
if (A == PA->LeftChild)
PA->LeftChild = B;
else
PA->RightChild = B;
}
else
{
root = B;
}
//设置平衡因子
A->bf = B->bf = 0;
}
template<class E, class K>
void AVLtree<E,K>::RRrotate(AVLNode<E,K> *PA, AVLNode<E,K> *A, AVLNode<E,K> *B)
{
//RR型的旋转
A->RightChild = B->LeftChild;
B->LeftChild = A;
if (PA) // A 是否有父节点
{
if (A == PA->LeftChild)
PA->LeftChild = B;
else
PA->RightChild = B;
}
else
{
root = B;
}
//设置平衡因子
A->bf = B->bf = 0;
}
template<class E, class K>
void AVLtree<E,K>::LRrotate(AVLNode<E,K> *PA,
AVLNode<E,K> *A, AVLNode<E,K> *B)
{
//LR型的旋转
AVLNode<E,K> *C = B->RightChild;
A->LeftChild = C->RightChild;
B->RightChild = C->LeftChild;
C->LeftChild = B;
C->RightChild = A;
if (PA) // A 是否有父节点
{
if (A == PA->LeftChild)
PA->LeftChild = C;
else
PA->RightChild = C;
}
else
{
root = C;
}
//设置平衡因子
int b = C->bf;
if (b == 1)
{
B->bf = 0;
A->bf = -1;
}
else if (b == -1)
{
B->bf = 1;
A->bf = 0;
}
else // b = 0
{
B->bf = A->bf = 0;
}
C->bf = 0;
}
template<class E, class K>
void AVLtree<E,K>::RLrotate(AVLNode<E,K> *PA,
AVLNode<E,K> *A, AVLNode<E,K> *B)
{
//RL型的旋转
AVLNode<E,K> *C = B->LeftChild;
A->RightChild = C->LeftChild;
B->LeftChild = C->RightChild;
C->LeftChild = A;
C->RightChild = B;
if (PA) // A 是否有父节点
{
if (A == PA->LeftChild)
PA->LeftChild = C;
else
PA->RightChild = C;
}
else
{
root = C;
}
//设置平衡因子
int b = C->bf;
if (b == 1)
{
B->bf = -1;
A->bf = 0;
}
else if (b == -1)
{
B->bf = 0;
A->bf = 1;
}
else // b = 0
{
B->bf = A->bf = 0;
}
C->bf = 0;
}
template<class E, class K>
AVLtree<E,K>& AVLtree<E,K>::Insert(const E& e)
{
AVLNode<E,K> *p = root,
*pp = 0, // p的父节点
*A = 0, // 平衡因子不为0 的最后一个节点
*PA; // A的父节点
//找到可以插入的地方
//同时记录最后一个平衡因子不为0的节点及其父节点
while (p)
{
if (p->bf)
{
A = p;
PA = pp;
}
pp = p;
// 将p移向子节点
if (e < p->data)
p = p->LeftChild;
else if (e > p->data)
p = p->RightChild;
else
throw BadInput();
/*if(e <= p->data)
p = p->LeftChild;
else
p = p->RightChild;*/
}
AVLNode<E,K> *r = new AVLNode<E,K> (e);
if (root)
{
if (e < pp->data)
pp->LeftChild = r;
else
pp->RightChild = r;
}
else
{
root = r;
return *this;
}
//查看是否需要再平衡,还是只是简单的刷新下平衡因子
if(A)
{
if (A->bf < 0) // bf = -1 在插入前
{
if (e < A->data)
{
//插入到A的左子树,左子树高度加1
//A新的平衡因子等于0, 不需要再平衡
A->bf = 0;
//刷新下从A到r的平衡因子
FixBF(A->LeftChild,r,e);
}
else
{
//插入到A的右子树
//A的平衡因子为-2, 需要再平衡
AVLNode<E,K> *B = A->RightChild;
if (e > B->data)
{
// RR型
FixBF(B->RightChild,r,e);
RRrotate(PA,A,B);
}
else
{
// RL型
FixBF(B->LeftChild,r,e);
RLrotate(PA,A,B);
}
}
}
else // bf = +1 在插入前
{
if (e > A->data)
{
//插入到A的右子树,右子树高度加1
//A新的平衡因子等于0, 不需要再平衡
A->bf = 0;
//刷新下从A到r的平衡因子
FixBF(A->RightChild,r,e);
}
else
{
//插入到A的左子树
//A的平衡因子为+2, 需要再平衡
AVLNode<E,K> *B = A->LeftChild;
if (e < B->data)
{
// LL型
FixBF(B->LeftChild,r,e);
LLrotate(PA,A,B);
}
else
{
// LR型
FixBF(B->RightChild,r,e);
LRrotate(PA,A,B);
}
}
}
}
else // A一直为0, 不需要再平衡
{
//刷新下从root到r的平衡因子
FixBF(root,r,e);
}
return *this;
}
template<class E, class K>
AVLtree<E,K>& AVLtree<E,K>::Delete(const K& k, E& e)
{
// 如果元素数量超过2^60, S栈将会溢出
Stack<AVLNode<E,K>*> S(100);
AVLNode<E,K> *p = root;
while (p && p->data != k)
{
S.Add(p);
if (k < p->data)
p = p->LeftChild;
else
p = p->RightChild;
}
if (!p)
throw BadInput();
e = p->data;
//p有两个子树的情况
if (p->LeftChild && p->RightChild)
{
//查找p左子树里元素值最大的节点
S.Add(p);
AVLNode<E,K> *s = p->LeftChild;
while (s->RightChild)
{
S.Add(s);
s = s->RightChild;
}
//将p左子树里元素值最大的节点等于p
p->data = s->data;
p = s;
}
//只有一个子树的情况
AVLNode<E,K> *c;
if (p->LeftChild)
c = p->LeftChild;
else
c = p->RightChild;
if (p == root)
{
root = c;
}
else
{
if (p == S.Top()->LeftChild)
S.Top()->LeftChild = c;
else
S.Top()->RightChild = c;
}
E f = p->data; //f也许不等于e
delete p;
AVLNode<E,K> *q;
try
{
S.Delete(q);
}
catch (OutOfBounds)
{
//根节点被删除了
return *this;
}
while (q)
{
if (f <= q->data)
{
//从q的左子树删除的
q->bf--;
//高度并未发生改变, 不需要再做什么
if (q->bf == -1)
return *this;
if (q->bf == -2)
{
//树变得不平衡了, 需要旋转
AVLNode<E,K> *B = q->RightChild,
*PA; // q就是A节点
// PA是A的父节点
try
{
S.Delete(PA);
}
catch (OutOfBounds)
{
//说明A是根节点
PA = 0;
}
switch (B->bf)
{
case 0: // L0型
RRrotate(PA,q,B);
B->bf = 1;
q->bf = -1;
return *this;
case 1: // L1型
RLrotate(PA,q,B);
break;
case -1:// L-1型
RRrotate(PA,q,B);
break;
}
q = PA;
}
else // q->bf == 0
{
try
{
S.Delete(q);
}
catch (OutOfBounds)
{
return *this;
}
}
}
else
{
//从q的右子树删除的
q->bf++;
//高度并未发生改变, 不需要再做什么
if (q->bf == 1)
return *this;
if (q->bf == 2)
{
//树变得不平衡了, 需要旋转
AVLNode<E,K> *B = q->LeftChild,
*PA; // q就是A节点
// PA是A的父节点
try
{
S.Delete(PA);
}
catch (OutOfBounds)
{
//说明A是根节点
PA = 0;
}
switch (B->bf)
{
case 0: // R0型
LLrotate(PA,q,B);
B->bf = -1;
q->bf = 1;
return *this;
case 1: // R1型
LLrotate(PA,q,B);
break;
case -1: // R-1 型
LRrotate(PA,q,B);
break;
}
q = PA;
}
else // q->bf == 0
{
try
{
S.Delete(q);
}
catch (OutOfBounds)
{
return *this;
}
}
}
}
return *this;
}
template<class E, class K>
void AVLtree<E,K>::InOutput(AVLNode<E,K> *t)
{
if(t)
{
InOutput(t->LeftChild);
cout << t->data << " ";
InOutput(t->RightChild);
}
}
template<class E, class K>
void AVLtree<E,K>::PostOutput(AVLNode<E,K> *t)
{
if(t)
{
PostOutput(t->LeftChild);
PostOutput(t->RightChild);
cout << t->data << " ";
}
}
view plaincopy to clipboardprint?
#ifndef AVLNode_
#define AVLNode_
template <class E, class K> class AVLtree;
template <class E, class K> class AVLtree2;
template <class E, class K> class DAVLtree;
template <class E, class K>
class AVLNode
{
friend AVLtree<E,K>;
friend AVLtree2<E,K>;
friend DAVLtree<E,K>;
public:
AVLNode() {LeftChild = RightChild = 0;}
AVLNode(const E& e){data = e; bf = 0; LeftChild = RightChild = 0; height = 0; }
private:
E data;
int bf;
int height;
AVLNode<E,K> *LeftChild,
*RightChild;
};
#endif
stack的手动实现
template<class T>
class Stack
{
public:
Stack(int MaxStackSize = 10);
~Stack() {delete [] stack;}
bool IsEmpty() const {return top == -1;}
bool IsFull() const {return top == MaxTop;}
T Top() const;
Stack<T>& Add(const T& x);
Stack<T>& Delete(T& x);
private:
int top;
int MaxTop;
T *stack;
};
template<class T>
Stack<T>::Stack(int MaxStackSize)
{
MaxTop = MaxStackSize - 1;
stack = new T[MaxStackSize];
top = -1;
}
template<class T>
T Stack<T>::Top() const
{
if (IsEmpty())
throw OutOfBounds();
return stack[top];
}
template<class T>
Stack<T>& Stack<T>::Add(const T& x)
{
if (IsFull())
throw NoMem();
stack[++top] = x;
return *this;
}
template<class T>
Stack<T>& Stack<T>::Delete(T& x)
{
if (IsEmpty())
throw OutOfBounds();
x = stack[top--];
return *this;
}