平衡树实现
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也是关于α对称的。
avltree.h
avltree.c
参考资料:
平衡二叉树的插入旋转
平衡二叉树,AVL树之图解篇
图解数据结构树之AVL树
数据结构&&AVL树原理、插入操作详解及实现
AVL树C语言实现
AVL树及其C语言实现
•(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;
}
参考资料:
相关文章推荐
- 使用AngularJS实现简单:全选和取消全选功能
- DNS解析原理
- UITableView优化技巧
- 从可执行文件手动删除.reloc
- ssh 登录出现的几种错误以及解决办法
- jQuery实现简单进度条效果
- 手把手教你部署VSAN见证虚拟设备 (Cormac)
- ios中UIApplication的作用及ios程序的启动过程
- Hadoop入门简介
- 面向对象
- note
- get/post 数据请求方式
- 自已创建Docker Base Image
- 基础C ,预处理指令,宏定义,文件包含
- 学习laravel遇到的问题
- View的位置参数
- HttpClient第一章(二)
- 诊断Java中的内存泄露
- vim配置(.vimrc)
- 响应式布局