您的位置:首页 > 理论基础 > 数据结构算法

数据结构与算法问题 AVL二叉平衡树

2017-05-19 21:31 351 查看
AVL树是带有平衡条件的二叉查找树。

这个平衡条件必须保持,并且它必须保证树的深度是O(logN)。

一棵AVL树是其每一个节点的左子树和右子树的高度最多差1的二叉查找树。

(空树的高度定义为-1)。

在插入以后。仅仅有那些从插入点到根节点的路径上的节点的平衡可能被改变,由于仅仅有这些节点的子树可能发生变化。当我们沿着这条路径上行到根并更新平衡信息时。我们能够找到一个节点,它的新平衡破坏了AVL条件。我们将指出怎样在第一个这种节点(即最深的节点)又一次平衡这棵树,并证明,这一又一次平衡保证整个树满足AVL特性。

让我们把必须又一次平衡的这个节点叫做a。因为随意节点最多有两个儿子,因此高度不平衡时。a点的两棵子树的高度差2。easy看出,这样的不平衡可能出如今以下四种情况中:

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: