AVL实现Word文档下载推荐.docx
《AVL实现Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《AVL实现Word文档下载推荐.docx(13页珍藏版)》请在冰豆网上搜索。
![AVL实现Word文档下载推荐.docx](https://file1.bdocx.com/fileroot1/2022-11/27/57c22562-6478-4de6-8201-3c51e32a4ff4/57c22562-6478-4de6-8201-3c51e32a4ff41.gif)
//----------AVL树基本操作------------
------------------------------
AvlTree
MakeEmpty(AvlTree
T);
Position
Find(ElemType
x,
FindMin(AvlTree
FindMax(AvlTree
static
Height(Position
P);
Insert(ElemType
Delete(ElemType
Retrieve(Position
//----------AVL树基本操作的算法实现--------------------
递归算法:
T)
if(T==NULL)
return
NULL;
else
if(T->
lchild
==
NULL)
T;
else
FindMin(T->
lchild);
}
rchild
FindMax(T->
rchild);
非递归算法:
if(T!
=NULL)
while(T->
!
=
T
T->
lchild;
rchild;
//返回P点的高度
P)
if(P==NULL)
-1;
P->
//在对一棵AVL树进行插入操作后,可能会破坏它的平衡条件,因此必须对新的AVL树进行调整,
这里用到了“单旋转”或“双旋转”的算法,分别适用于:
单左旋转(SingleRotateWithLeft);
对结点p的左孩子的左子树进行一次插入
单右旋转(SingleRotateWithRight);
对结点p的右孩子的右子树进行一次插入
双左旋转(DoubleRotateWithLeft);
对结点p的左孩子的右子树进行一次插入
双右旋转(DoubleRotateWithRight);
对结点p的右孩子的左子树进行一次插入
SingleRotateWithLeft(Position
K2)
K1;
K1
K2->
//在K2和K1之间进行一次单左旋转
K1->
K2;
height
Max(Height(K2->
lchild),
Height(K2->
rchild))
+
1;
Max(Height(K1->
Height(K1->
SingleRotateWithRight(Position
//在K2和K1之间进行一次单右旋转
DoubleRotateWithLeft(Position
K3)
K3->
SingleRotateWithRight(K3->
SingleRotateWithLeft(K3);
//在K3和K2之间进行一次单左旋转
DoubleRotateWithRight(Position
SingleRotateWithLeft(K3->
SingleRotateWithRight(K3);
//在K3和K2之间进行一次单右旋转
//向AVL树插入结点的操作
Insert(float
if(T
(Position)malloc(sizeof(struct
avlnode));
puts("
wrong"
);
exit
(1);
data
x;
0;
x)//不做任何插入操作
;
>
x)//把s所指结点插入到左子树中
Insert(x,
if(Height(T->
lchild)
-
Height(T->
rchild)
2)
//若平衡被破坏
if(x
<
lchild->
data)
//若x比T的左孩子小,对T单左旋转
SingleRotateWithLeft(T);
//否则,对T双左旋转
DoubleRotateWithLeft(T);
//把s所指结点插入到右子树中
2)
rchild->
//若x比T的右孩子大,对T单右旋转
SingleRotateWithRight(T);
//否则,对T双右旋转
DoubleRotateWithRight(T);
Max(Height(T->
Max(int
a,
b)
if(a
a;
b;
还有一种AVL树,它的结构中不包含高度特征,但包含一个平衡因子bf,用来判断结点的平衡性,若左孩子比右孩子高,则bf==1;
否则,bf==-1;
若左右相等则bf==0。
enum
BALANCE{LH
1,
EH
0,
RH
-1};
BALANCE
bf;
//比普通二杈有序树多了一个平衡因子信息
avlnode
对结点p的左孩子的左子树进行一次插入
对结点p的右孩子的右子树进行一次插入
对结点p的左孩子的右子树进行一次插入
对结点p的右孩子的左子树进行一次插入
//在K2和K1之间进行一次单左旋转
//在K2和K1之间进行一次单右旋转
//在K3和K2之间进行一次单左旋转
//在K3和K2之间进行一次单右旋转
LeftBalance(AvlTree
T)
//左平衡处理
lT
switch
(lT->
bf)
//检查左树的平衡度,并做相应处理
case
LH
:
//若新结点插入在T的左孩子的左子树上,对T单左旋转
bf
lT->
EH;
//重新设置平衡度
break;
rT
//若新结点插入在T的左孩子的右子树上,对T双左旋转,并重新设置平衡度
(rT->
bf)
RH;
LH;
break
rT->
RightBalance(AvlTree
//右平衡处理
//检查右树的平衡度,并做相应处理
//若新结点插入在T的右孩子的右子树上,对T单右旋转
//若新结点插入在T的右孩子的左子树上,对T双右旋转,并重新设置平衡度
//向AVL树插入结点的操作
T,
bool
&
taller)
taller
true;
//插入新结点,树“长高”,置taller为真值
x)//不做任何插入操作
false;
//树未长高,置taller为假值
x)//把x插入到左子树中
lchild,
taller);
if
(taller)//已经插入左子树,且树“长高”,需要检查平衡度,并做相应处理
switch(T->
LeftBalance(T);
//原本左树高于右树,需做左平衡处理,树高不变
//原本左右等高,现在左高于右,且树“长高”
//原本右树高于左树,现在左右等高,树高不变
//把x插入到右子树中,仿照处理左树的方法处理
rchild,
(taller)
RightBalance(T);
AVL树应用示例:
/*输入一组数,存储到AVL树中,并进行输出*/
#include
iostream>
u