您的位置:首页 > 编程语言 > C语言/C++

平衡二叉树(AVL树)的创建,查找

2016-02-01 15:30 597 查看
#include<stdio.h>
#include<malloc.h>
#define MAXSIZE 10
int a[MAXSIZE]={10,23,22,4,5,6,66,13,1,0};
typedef struct node
{
int key;                                   //关键字项
int bf;                                    //平衡因子
struct node *lchild,*rchild;               //左右孩子指针
}BSTnode;
void LeftProcess(BSTnode *&p,int &taller);
void RightProcess(BSTnode *&p,int &taller);
void Delete2(BSTnode *q,BSTnode *&r,int &taller);
void LeftProcess1(BSTnode *&p,int &taller);
void RightProcess1(BSTnode *&p,int &taller);
int InsertAVL(BSTnode *&b,int k,int &taller)
{
if(b==NULL)                                //原树为空树,插入新节点,树长高,置taller=1
{
b=(BSTnode *)malloc(sizeof(BSTnode));
b->key=k;
b->lchild=b->rchild=NULL;
b->bf=0;
taller=1;
}

else
{
if(k==b->key)                              //树中已存在和k相同关键字的节点,不能插入
{
taller=0;
return 0;
}
if(k<b->key)                              //应继续在*b的左子树中搜索,即在左子树插入
{
if((InsertAVL(b->lchild,k,taller))==0)//未插入
return 0;
if(taller==1)                         //已插入*b的左子树,左子树长高
LeftProcess(b,taller);
}
else                                      //应继续在*b的右子树中搜索,即在右子树插入
{
if((InsertAVL(b->rchild,k,taller))==0)//未插入
return 0;
if(taller==1)                         //已插入*b的右子树,右子树长高
RightProcess(b,taller);
}
}
}
void LeftProcess(BSTnode *&p,int &taller)
{
BSTnode *p1,*p2;
if(p->bf==0)                             //情况1,插入前p->bf=0
{
p->bf=1;
taller=1;                            //子树增高
}
else if(p->bf==-1)                       //情况2,插入前p->bf=-1
{
p->bf=0;
taller=0;                            //子树没有增高
}
else                                     //情况3,p->bf=1
{
p1=p->lchild;
if(p1->bf==1)                        //做LL调整
{
p->lchild=p1->rchild;
p1->rchild=p;
p->bf=p1->bf=0;
p=p1;
}
else if(p1->bf==-1)                 //做LR调整
{
p2=p1->rchild;
p1->rchild=p2->lchild;
p2->lchild=p1;
p->lchild=p->rchild;
p2->rchild;
if(p2->bf==0)                   //K处在*b位置上(叶子节点)
p->bf=p1->bf=0;
else if(p2->bf==1)              //k处于*b的左子树上
{
p1->bf=0;
p->bf=-1;
}
else                           //k处在*b的右子树上
{
p1->bf=1;
p->bf=0;
}
p=p2;                          //仍然将p指向新的根节点,并置其bf值为0
p->bf=0;
}
taller=0;                          //子树没有增高
}
}
void RightProcess(BSTnode *&p,int &taller)
{
BSTnode *p1,*p2;
if(p->bf==0)                             //情况1,插入前p->bf=0
{
p->bf=-1;
taller=-1;                            //子树增高
}
else if(p->bf==1)                       //情况2,插入前p->bf=-1
{
p->bf=0;
taller=0;                            //子树没有增高
}
else                                     //情况3,p->bf=1
{
p1=p->rchild;
if(p1->bf==-1)                        //做RR调整
{
p->rchild=p1->lchild;
p1->lchild=p;
p->bf=p1->bf=0;
p=p1;
}
else if(p1->bf==1)                 //做RL调整
{
p2=p1->lchild;
p1->lchild=p2->rchild;
p2->rchild=p1;
p->rchild=p->lchild;
p2->lchild;
if(p2->bf==0)                   //K处在*b位置上(叶子节点)
p->bf=p1->bf=0;
else if(p2->bf==-1)              //k处于*b的左子树上
{
p1->bf=0;
p->bf=1;
}
else                           //k处在*b的右子树上
{
p1->bf=-1;
p->bf=0;
}
p=p2;                          //仍然将p指向新的根节点,并置其bf值为0
p->bf=0;
}
taller=0;                          //子树没有增高
}
}
void InOrder(BSTnode *p)                    //中序遍历
{
if(p!=NULL)
{
InOrder(p->lchild);
printf("%d ",p->key);
InOrder(p->rchild);
}
}
int DeleteAVL(BSTnode *&p,int x,int &taller)//从根节点为*p的AVL树中删除关键字为x的节点
{
int k;
BSTnode *q;
if(p==NULL)
return 0;
else if(x<p->key)
{
k=DeleteAVL(p->lchild,x,taller);
if(taller==1)
LeftProcess1(p,taller);        //需要左处理
return k;
}
else if(x>p->key)
{
k=DeleteAVL(p->rchild,x,taller);
if(taller==1)
RightProcess1(p,taller);         //需要右处理
return k;
}
else                                  //找到了关键字为x的节点,由p指向它
{
q=p;
if(p->rchild==NULL)                //被删除节点右子树为空
{
p=p->lchild;
free(q);
taller=1;
}
else if(p->lchild==NULL)           //被删除节点左字树为空
{
p=p->rchild;
free(q);
taller;
}
else                               //被删除节点左右子树都不为空
{
Delete2(q,q->lchild,taller);
if(taller==1)
LeftProcess1(q,taller);    //需要左处理
p=q;
}
return 1;
}
}
void Delete2(BSTnode *q,BSTnode *&r,int &taller)//被删除节点左右子树都不为空
{
if(r->rchild==NULL)
{
q->key=r->key;
q=r;
r=r->lchild;
free(q);
taller=1;
}
else
{
Delete2(q,r->rchild,taller);             //递归找最右下节点,找到后进行删除
if(taller==1)
RightProcess1(r,taller);           //需要右处理
}
}
void LeftProcess1(BSTnode *&p,int &taller)      //删除左处理算法
{
BSTnode *p1,*p2;
if(p->bf==1)                                //情况1,p-bf=1;
{
p->bf=0;
taller=1;
}
else if(p->bf==0)                           //情况2,p->bf=0;
{
p->bf=-1;
taller=0;
}
else
{
p1=p->rchild;
if(p1->bf==0)
{
p->rchild=p1->lchild;
p1->lchild=p;
p1->bf=1;
p->bf=-1;
p=p1;
taller;
}
else if(p1->bf==-1)
{
p->rchild=p1->lchild;
p1->lchild=p;
p->bf=p1->bf=0;
p=p1;
taller=1;
}
else
{
p2=p1->lchild;
p1->lchild=p2->rchild;
p2->rchild=p1;
p->rchild=p2->lchild;
p2->lchild=p;
if(p2->bf==0)
{
p->bf=0;
p1->bf=0;
}
else if(p2->bf==-1)
{
p->bf=1;
p1->bf=0;
}
else
{
p->bf=0;
p1->bf=-1;
}
p2->bf=0;
p=p2;
taller=1;
}
}
}
void RightProcess1(BSTnode *&p,int &taller)      //删除右处理算法
{
BSTnode *p1,*p2;
if(p->bf==-1)                                //情况1,p-bf=-1;
{
p->bf=0;
taller=-1;
}
else if(p->bf==0)                           //情况2,p->bf=0;
{
p->bf=1;
taller=0;
}
else
{
p1=p->lchild;
if(p1->bf==0)
{
p->lchild=p1->rchild;
p1->rchild=p;
p1->bf=-1;
p->bf=1;
p=p1;
taller;
}
else if(p1->bf==1)
{
p->lchild=p1->rchild;
p1->rchild=p;
p->bf=p1->bf=0;
p=p1;
taller=-1;
}
else
{
p2=p1->rchild;
p1->rchild=p2->lchild;
p2->lchild=p1;
p->lchild=p2->rchild;
p2->rchild=p;
if(p2->bf==0)
{
p->bf=0;
p1->bf=0;
}
else if(p2->bf==1)
{
p->bf=-1;
p1->bf=0;
}
else
{
p->bf=0;
p1->bf=1;
}
p2->bf=0;
p=p2;
taller=-1;
}
}
}
int main()
{
BSTnode *p;
int i,taller;
for(i=0;i<MAXSIZE;i++)                  //将数组a[]中元素插入到AVL
InsertAVL(p,a[i],taller);
printf("中序遍历:\n");                  //中序遍历,将数组中的元素从小到大排列
InOrder(p);
printf("\n");
DeleteAVL(p,4,taller);
printf("删除关键字为4的结点后,中序遍历:\n");
InOrder(p);
printf("\n");

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息