您的位置:首页 > 其它

平衡树实现

2015-12-07 23:06 225 查看
•定义1(AVL树):Anemptybinarytreeisheightbalanced.IfTisanonemptybinarytreewithTLandTRasitsleftandrightsubtrees,thenTisheightbalancediff
•(1)TLandTRareheightbalanced,and
•(2)|hL-hR|£1wherehLandhRaretheheightsofTLandTR,respectively.
•定义2(平衡因子):ThebalancefactorBF(node)=hL-hR.InanAVLtree,BF(node)=-1,0,or1.

AVL树的最少节点数



•我们把必须重新平衡的节点叫做α,节点α的两棵子树的高度差为2。容易看出,这种不平衡可以出现在以下四种情况中:
•1、对α的左儿子的左子树进行一次插入。
•2、对α的左儿子的右子树进行一次插入。
•3、对α的右儿子的左子树进行一次插入。
•4、对α的右儿子的右子树进行一次插入。
•情况1和4是关于α对称的,情况2和3也是关于α对称的。













staticPosition
SingleRotateWithLeft(PositionK2)
{
PositionK1;

K1=K2->Left;
K2->Left=K1->Right;
K1->Right=K2;

K2->Height=Max(Height(K2->Left),Height(K2->Right))+1;
K1->Height=Max(Height(K1->Left),K2->Height)+1;

returnK1;/*Newroot*/
}


SingleRotateWithLeft单旋转例程



staticPosition
DoubleRotateWithLeft(PositionK3)
{
/*RotatebetweenK1andK2*/
K3->Left=SingleRotateWithRight(K3->Left);

/*RotatebetweenK3andK2*/
returnSingleRotateWithLeft(K3);
}


DoubleRotateWithLeft双旋转例程







avltree.h

/*平衡树的声明*/
typedefintElementType;

/*START:fig4_35.txt*/
#ifndef_AvlTree_H
#define_AvlTree_H

structAvlNode;
typedefstructAvlNode*Position;
typedefstructAvlNode*AvlTree;

AvlTreeMakeEmpty(AvlTreeT);
PositionFind(ElementTypeX,AvlTreeT);
PositionFindMin(AvlTreeT);
PositionFindMax(AvlTreeT);
AvlTreeInsert(ElementTypeX,AvlTreeT);
AvlTreeDelete(ElementTypeX,AvlTreeT);
ElementTypeRetrieve(PositionP);

//以下是补充
voidPrintTree(AvlTreeT);
AvlTreeRemove(constElementTypeX,AvlTreeT);
AvlTreeRemove(ElementTypeX,AvlTreeT);

#endif/*_AvlTree_H*/
/*END*/


avltree.c

#include"avltree.h"
#include<stdlib.h>
#include"fatal.h"

structAvlNode
{
ElementTypeElement;
AvlTreeLeft;
AvlTreeRight;
intHeight;
};

/*置空平衡树*/
AvlTree
MakeEmpty(AvlTreeT)
{
if(T!=NULL)
{
MakeEmpty(T->Left);
MakeEmpty(T->Right);
free(T);
}
returnNULL;
}

/*查找元素在平衡树中的位置*/
Position
Find(ElementTypeX,AvlTreeT)
{
if(T==NULL)
returnNULL;
if(X<T->Element)
returnFind(X,T->Left);
else
if(X>T->Element)
returnFind(X,T->Right);
else
returnT;
}

/*找平衡树的最小元素,递归实现*/
Position
FindMin(AvlTreeT)
{
if(T==NULL)
returnNULL;
else
if(T->Left==NULL)
returnT;
else
returnFindMin(T->Left);
}

/*找平衡树的最大元素,非递归实现*/
Position
FindMax(AvlTreeT)
{
if(T!=NULL)
while(T->Right!=NULL)
T=T->Right;

returnT;
}

/*START:fig4_36.txt*/

/*返回节点的高度*/
staticint
Height(PositionP)
{
if(P==NULL)
return-1;
else
returnP->Height;
}
/*END*/

/*返回两个数的最大值*/
staticint
Max(intLhs,intRhs)
{
returnLhs>Rhs?Lhs:Rhs;
}

/*START:fig4_39.txt*/
/*ThisfunctioncanbecalledonlyifK2hasaleftchild*/
/*Performarotatebetweenanode(K2)anditsleftchild*/
/*Updateheights,thenreturnnewroot*/

/*
左左(LL)情况的右旋

K2
/k1
K1=>/\
/kk2
k

*/
staticPosition
SingleRotateWithLeft(PositionK2)
{
PositionK1;

K1=K2->Left;
K2->Left=K1->Right;
K1->Right=K2;

K2->Height=Max(Height(K2->Left),Height(K2->Right))+1;
K1->Height=Max(Height(K1->Left),K2->Height)+1;

returnK1;/*Newroot*/
}
/*END*/

/*ThisfunctioncanbecalledonlyifK1hasarightchild*/
/*Performarotatebetweenanode(K1)anditsrightchild*/
/*Updateheights,thenreturnnewroot*/

/*
右右(RR)情况的左旋

k1
\
k2=>k2
\/\
kk1k

*/
staticPosition
SingleRotateWithRight(PositionK1)
{
PositionK2;

K2=K1->Right;
K1->Right=K2->Left;
K2->Left=K1;

K1->Height=Max(Height(K1->Left),Height(K1->Right))+1;
K2->Height=Max(Height(K2->Right),K1->Height)+1;

returnK2;/*Newroot*/
}

/*START:fig4_41.txt*/
/*ThisfunctioncanbecalledonlyifK3hasaleft*/
/*childandK3'sleftchildhasarightchild*/
/*Dotheleft-rightdoublerotation*/
/*Updateheights,thenreturnnewroot*/

/*

左右(LR)情况的左右旋转

k3k3
//
k1=>k2=>k2
\//\
k2k1k1k3

*/

staticPosition
DoubleRotateWithLeft(PositionK3)
{
/*RotatebetweenK1andK2*/
K3->Left=SingleRotateWithRight(K3->Left);

/*RotatebetweenK3andK2*/
returnSingleRotateWithLeft(K3);
}
/*END*/

/*ThisfunctioncanbecalledonlyifK1hasaright*/
/*childandK1'srightchildhasaleftchild*/
/*Dotheright-leftdoublerotation*/
/*Updateheights,thenreturnnewroot*/

/*

右左(RL)情况的右左旋转

k1k1
\\
k3=>k2=>k2
/\/\
k2k3k1k3

*/

staticPosition
DoubleRotateWithRight(PositionK1)
{
/*RotatebetweenK3andK2*/
K1->Right=SingleRotateWithLeft(K1->Right);

/*RotatebetweenK1andK2*/
returnSingleRotateWithRight(K1);
}

/*START:fig4_37.txt*/
/*平衡树的插入*/
AvlTree
Insert(ElementTypeX,AvlTreeT)
{
if(T==NULL)
{
/*Createandreturnaone-nodetree*/
T=malloc(sizeof(structAvlNode));
if(T==NULL)
FatalError("Outofspace!!!");
else
{
T->Element=X;T->Height=0;
T->Left=T->Right=NULL;
}
}
else
if(X<T->Element)
{
T->Left=Insert(X,T->Left);
if(Height(T->Left)-Height(T->Right)==2)
if(X<T->Left->Element)
T=SingleRotateWithLeft(T);
else
T=DoubleRotateWithLeft(T);
}
else
if(X>T->Element)
{
T->Right=Insert(X,T->Right);
if(Height(T->Right)-Height(T->Left)==2)
if(X>T->Right->Element)
T=SingleRotateWithRight(T);
else
T=DoubleRotateWithRight(T);
}
/*ElseXisinthetreealready;we'lldonothing*/

T->Height=Max(Height(T->Left),Height(T->Right))+1;
returnT;
}
/*END*/

AvlTree
Delete(ElementTypeX,AvlTreeT)
{
printf("Sorry;Deleteisunimplemented;%dremains\n",X);
returnT;
}

/*返回某节点的值*/
ElementType
Retrieve(PositionP)
{
returnP->Element;
}

//以下是补充
//
voidPrintTree(AvlTreeT)
{
if(T!=NULL)
{
PrintTree(T->Left);
printf("%3d",Retrieve(T));
PrintTree(T->Right);
}
}

AvlTreeRemove(ElementTypeX,AvlTreeT)
{
if(T==NULL)
returnNULL;//没有找到要删除的值,donothing
if(X<T->Element)
{
T->Left=Remove(X,T->Left);
if(Height(T->Right)-Height(T->Left)==2)
{
//右子树比左子树高2,那么在删除操作之前右子树比左子树高1,
//也就是说T的右子树必然不为空,甚至必然有非空子树(高度至少为1).
AvlTrees=T->Right;
if(Height(s->Left)>Height(s->Right))
T=DoubleRotateWithRight(T);//右双旋转
else
T=SingleRotateWithRight(T);//右单旋转
}
else
//不需要调整就满足平衡条件的话,只需要重新计算其高度就好
T->Height=Max(Height(T->Left),Height(T->Right))+1;
}
elseif(X>T->Element)
{

T->Right=Remove(X,T->Right);
if(Height(T->Left)-Height(T->Right)==2)
{
AvlTrees=T->Left;
if(Height(s->Right)>Height(s->Left))
T=DoubleRotateWithLeft(T);//左双旋转
else
T=SingleRotateWithLeft(T);//左单旋转
}
else
T->Height=Max(Height(T->Left),Height(T->Right))+1;
}
else
{
if(T->Left&&T->Right)//T的左右子树都非空,把Remove操作转移到只有一个非空子树的结点或者叶子结点上去
{
if(Height(T->Left)>Height(T->Right))
//把Remove操作往更高的那颗子树上转移
{
//左子树中的最大值
T->Element=FindMax(T->Left)->Element;
T->Left=Remove(T->Element,T->Left);
}
else
{
//右子树中的最小值
T->Element=FindMin(T->Right)->Element;
T->Right=Remove(T->Element,T->Right);
}
}
else
{
AvlTreeoldnode=T;
T=T->Left?T->Left:T->Right;
free(oldnode);
}
}
returnT;
}


参考资料:

平衡二叉树的插入旋转

平衡二叉树,AVL树之图解篇

图解数据结构树之AVL树

数据结构&&AVL树原理、插入操作详解及实现

AVL树C语言实现

AVL树及其C语言实现
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: