AVL树是带有平衡条件的二叉查找树。这个平衡条件必须保持,而且它必须保证树的深度是O(logN)。
一棵AVL树是其每个节点的左子树和右子树的高度最多差1的二叉查找树。(空树的高度定义为-1)。
在插入以后,只有那些从插入点到根节点的路径上的节点的平衡可能被改变,因为只有这些节点的子树可能发生变化。当我们沿着这条路径上行到根并更新平衡信息时,我们可以找到一个节点,它的新平衡破坏了AVL条件。我们将指出如何在第一个这样的节点(即最深的节点)重新平衡这棵树,并证明,这一重新平衡保证整个树满足AVL特性。
让我们把必须重新平衡的这个节点叫做a。由于任意节点最多有两个儿子,因此高度不平衡时,a点的两棵子树的高度差2。容易看出,这种不平衡可能出现在下面四种情况中:
1.对a的左儿子的左子树进行一次插入
2.对a的左儿子的右子树进行一次插入
3.对a的右儿子的左子树进行一次插入
4.对a的右儿子的右子树进行一次插入
第一种情况是插入发生在“外边"的情况(即左—左的情况或右—右的情况),该情况通过对树的一次单旋转而完成调整。第二种情况是插入发生在”内部“的情形(即左—右的情况或右—左的情况),该情况通过稍微复杂些的双旋转来处理。
AVL树本质上还是一棵二叉搜索树,它的特点是:
-
本身首先是一棵二叉搜索树。
-
带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1
#include <iostream>
using namespace std;
const int LH = 1;
const int EH = 0;
const int RH = -1;
bool TRUE = 1;
bool FALSE = 0;
typedef struct BSTNode
{
int key;
int bf;
BSTNode *lchild, *rchild;
}BSTNode;
//中序遍历
void inordertree(BSTNode * &root)
{
if (root)
{
inordertree(root->lchild);
cout << root->key<<",";
inordertree(root->rchild);
}
}
//前序遍历
void preordertree(BSTNode * &root)
{
if (root)
{
cout << root->key<<",";
preordertree(root->lchild);
preordertree(root->rchild);
}
}
//右旋
void R_Rotate(BSTNode * &p)
{
BSTNode *lc = p->lchild;
p->lchild = lc->rchild;
lc->rchild = p;
p = lc;
}
//左旋
void L_Rotate(BSTNode *& p)
{
BSTNode *rc = p->rchild;
p->rchild = rc->lchild;
rc->lchild = p;
p = rc;
}
void LeftBalance(BSTNode * &T)
{
BSTNode *lc = T->lchild;
switch (lc->bf)
{
case LH:
T->bf = lc->bf = EH;
R_Rotate(T);
break;
case RH:
BSTNode *rd = lc->rchild;
switch (rd->bf)
{
case LH:
T->bf = RH;
lc->bf = EH;
break;
case EH:
T->bf = lc->bf = EH;
lc->bf = LH;
break;
}
rd->bf = EH;
L_Rotate(T->lchild);//先左旋
R_Rotate(T);
break;
}
}
void RightBalance(BSTNode *& T)
{
BSTNode *rc = T->rchild;
switch (rc->bf)
{
case RH:
T->bf = rc->bf = EH;
L_Rotate(T);
break;
case LH:
BSTNode *ld = rc->lchild;
switch (ld->bf)
{
case RH:
T->bf = LH;
rc->bf = EH;
break;
case EH:
T->bf = rc->bf = EH;
break;
case LH:
T->bf = EH;
rc->bf = RH;
break;
}
ld->bf = EH;
R_Rotate(T->rchild);
L_Rotate(T);
break;
}
}
int insertAVL(BSTNode *& t, int e, bool &taller)
{
if (!t)
{
t = new BSTNode;
t->key = e;
t->lchild = t->rchild = NULL;
t->bf = EH;
taller = TRUE;
}
else
{
if (e == t->key)
{
taller = FALSE;
return 0;
}
if (e < t->key)
{
if (!insertAVL(t->lchild, e,taller))
return 0;
if (taller)
{
switch (t->bf)
{
case LH:
LeftBalance(t);
taller = FALSE;
break;
case EH:
t->bf = LH;
taller = TRUE;
break;
case RH:
t->bf = EH;
taller = FALSE;
break;
}
}
}
else
{
if (!insertAVL(t->rchild, e, taller))
return 0;
if (taller)
{
switch (t->bf)
{
case RH:
RightBalance(t);
taller = FALSE;
break;
case EH:
t->bf = RH;
taller = TRUE;
break;
case LH:
t->bf = EH;
taller = FALSE;
break;
}
}
}
}
return 1;
}
BSTNode *search(BSTNode *t, int key)
{
BSTNode *p = t;
while (p)
{
if (p->key == key)
return p;
else if (p->key < key)
p = p->rchild;
else
p = p->lchild;
}
return p;
}
int main()
{
BSTNode *root = NULL;
BSTNode *r;
bool taller = FALSE;
int array[] = { 13, 24, 37, 90, 53 };
for (int i = 0; i < 5; i++)
insertAVL(root, array[i], taller);
cout << "inorder traverse..." << endl;
inordertree(root);
cout << endl;
cout << "preorder traverse..." << endl;
preordertree(root);
cout << endl;
cout << "search key..." << endl;
r = search(root, 37);
if (r)
{
cout << r->key << endl;
}
else
{
cout << "not find" << endl;
}
system("pause");
return 0;
}