if(T->lchild)
PrintBT(T->lchild,m+1);
}
}
//对*p为根的进行右旋转处理
voidRight_Balance(BTree&p)
{
BTreelc;
lc=p->lchild;//lc指向的*p左子树根结点
p->lchild=lc->rchild;//lc的右子树挂接为*p的左子树
lc->rchild=p;
p=lc;//p指向新的结点
}
//对以*p为根的二叉排序树作左旋处理
voidLeft_Balance(BTree&p)
{
BTreerc;
rc=p->rchild;//指向的*p右子树根结点
p->rchild=rc->lchild;//rc左子树挂接到*p的右子树
rc->lchild=p;
p=rc;//p指向新的结点
}
//对以指针T所指结点为根的二叉树作左平衡旋转处理
voidLeft_Root_Balance(BTree&T)//左左型和左右型
{
BTreelc,rd;
lc=T->lchild;//指向*T的左子树根结点
switch(lc->bf)//检查*T的左子树的平衡度,并作相应平衡处理
{
caseLH:
//新结点插入在*T的左孩子的左子树上,要作单右旋处理
T->bf=lc->bf=EH;
Right_Balance(T);
break;
caseRH:
//新结点插入在*T的左孩子的右子树上,要作双旋处理
rd=lc->rchild;//rd指向*T的左孩子的右子树根
switch(rd->bf)//修改*T及其左孩子的平衡因子
{
caseLH:
T->bf=RH;
lc->bf=EH;
break;
caseEH:
T->bf=lc->bf=EH;
break;
caseRH:
T->bf=EH;
lc->bf=LH;
break;
}
rd->bf=EH;
Left_Balance(T->lchild);//对*T的左子树作左旋平衡处理
Right_Balance(T);//对*T作右旋平衡处理
}
}
//对以指针T所指结点为根的二叉树作右平衡旋转处理
voidRight_Root_Balance(BTree&T)
{
BTreerc,ld;
rc=T->rchild;//指向*T的右子树的根节点
switch(rc->bf)
{
caseRH:
//新节点插在*T
T->bf=rc->bf=EH;
Left_Balance(T);
break;
caseLH:
ld=rc->lchild;//ld指向*T的右孩子的左子树根
switch(ld->bf)
{
caseLH:
T->bf=EH;
rc->bf=RH;
break;
caseEH:
T->bf=rc->bf=EH;
break;
caseRH:
T->bf=LH;
rc->bf=EH;
break;
}
ld->bf=EH;
Right_Balance(T->rchild);//对*T的右子树作左旋平衡处理
Left_Balance(T);//对*T作左旋平衡处理
}
}
//插入结点i,若T中存在和i相同关键字的结点,则插入一个数据元素为i的新结点,并返回1,否则返回0
boolInsertBT(BTree&T,inti,bool&taller)
{
if(!
T)//插入新结点,树“长高”,置taller为true
{
T=(BTree)malloc(sizeof(BTNode));
T->data=i;
T->lchild=T->rchild=NULL;
T->bf=EH;//置平衡因子为零
taller=true;
}
else
{
if(ET(i,T->data))//树中已存在和有相同关键字的结点是否i==T->data
{
taller=false;//将taller置为false表示插入失败
cout<<"已存在相同关键字的结点"<return0;
}
if(LT(i,T->data))//应继续在*T的左子树中进行搜索
{
if(!
InsertBT(T->lchild,i,taller))
return0;
}
else//应继续在*T的右子树中进行搜索
{
if(!
InsertBT(T->rchild,i,taller))
return0;
}
}
return1;
}
/*删除结点时左平衡旋转处理*/
voidLeft_Root_Balance_det(BTree&p,int&shorter)
{
BTreep1,p2;
if(p->bf==1)//p结点的左子树高,删除结点后p的bf减,树变矮
{
p->bf=0;
shorter=1;
}
elseif(p->bf==0)//p结点左、右子树等高,删除结点后p的bf减,树高不变
{
p->bf=-1;
shorter=0;
}
else//p结点的右子树高
{
p1=p->rchild;//p1指向p的右子树
if(p1->bf==0)//p1结点左、右子树等高,删除结点后p的bf为-2,进行左旋处理,树高不变
{
Left_Balance(p);
p1->bf=1;
p->bf=-1;
shorter=0;
}
elseif(p1->bf==-1)//p1的右子树高,左旋处理后,树变矮
{
Left_Balance(p);
p1->bf=p->bf=0;
shorter=1;
}
else//p1的左子树高,进行双旋处理(先右旋后左旋),树变矮
{
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;
}
elseif(p2->bf==-1)
{
p->bf=1;
p1->bf=0;
}
else
{
p->bf=0;
p1->bf=-1;
}
p2->bf=0;
p=p2;
shorter=1;
}
}
}
/*删除结点时右平衡旋转处理*/
voidRight_Root_Balance_det(BTree&p,int&shorter)
{
BTreep1,p2;
if(p->bf==-1)
{
p->bf=0;
shorter=1;
}
elseif(p->bf==0)
{
p->bf=1;
shorter=0;
}
else
{
p1=p->lchild;
if(p1->bf==0)
{
Right_Balance(p);
p1->bf=-1;
p->bf=1;
shorter=0;
}
elseif(p1->bf==1)
{
Right_Balance(p);
p1->bf=p->bf=0;
shorter=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;
}
elseif(p2->bf==1)
{
p->bf=-1;
p1->bf=0;
}
else
{
p->bf=0;
p1->bf=1;
}
p2->bf=0;
p=p2;
shorter=1;
}
}
}
/*删除结点*/
voidDelete(BTreeq,BTree&r,int&shorter)
{
if(r->rchild==NULL)
{
q->data=r->data;
q=r;
r=r->lchild;
free(q);
shorter=1;
}
else
{
Delete(q,r->rchild,shorter);
if(shorter==1)
Right_Root_Balance_det(r,shorter);
}
}
/*二叉树的删除操作*/
intDeleteAVL(BTree&p,intx,int&shorter)
{
intk;
BTreeq;
if(p==NULL)
{
cout<<"不存在要删除的关键字!
!
"<return0;
}
elseif(xdata)//在p的左子树中进行删除
{
k=DeleteAVL(p->lchild,x,shorter);
if(shorter==1)
Left_Root_Balance_det(p,shorter);
returnk;
}
elseif(x>p->data)//在p的右子树中进行删除
{
k=DeleteAVL(p->rchild,x,shorter);
if(shorter==1)
Right_Root_Balance_det(p,shorter);
returnk;
}
else
{
q=p;
if(p->rchild==NULL)//右子树空则只需重接它的左子树
{
p=p->lchild;
free(q);
shorter=1;
}
elseif(p->lchild==NULL)//左子树空则只需重接它的右子树
{
p=p->rchild;
free(q);
shorter=1;
}
else//左右子树均不空
{
Delete(q,q->lchild,shorter);
if(shorter==1)
Left_Root_Balance_det(p,shorter);
p=q;
}
return1;
}
}
/*调平二叉树具体方法*/
boolSetAVL(BTree&T,inti,bool&taller)
{
if(!
T)//插入新结点,树“长高”,置taller为true
{
T=(BTree)malloc(sizeof(BTNode));
T->data=i;
T->lchild=T->rchild=NULL;
T->bf=EH;
taller=true;
}
else
{
if(ET(i,T->data))//树中已存在和有相同关键字的结点
{
taller=false;
cout<<"已存在相同关键字的结点"<return0;
}
if(LT(i,T->data))//应继续在*T的左子树中进行搜索
{
if(!
SetAVL(T->lchild,i,taller))
return0;
if(taller)//已插入到*T的左子树中且左子树“长高”
switch(T->bf)//检查*T的平衡度
{
caseLH:
//原本左子树比右子树高,需要作左平衡处理
Left_Root_Balance(T);
taller=false;
break;
caseEH:
//原本左子树、右子等高,现因左子树增高而使树增高
T->bf=LH;
taller=true;
break;
caseRH:
//原本右子树比左子树高,现左、右子树等高
T->bf=EH;
taller=false;
break;
}
}
else//应继续在*T的右子树中进行搜索
{
if(!
SetAVL(T->rchild,i,taller))
return0;
if(taller)//已插入到*T的右子树中且右子树“长高”
switch(T->bf)//检查*T的平衡度
{
caseLH:
//原本左子树比右子树高,现左、右子树等高
T->bf=EH;
taller=false;
break;
caseEH:
//原本左子树、右子等高,现因右子树增高而使树增高
T->bf=RH;
taller=true;
break;
caseRH:
//原本右子树比左子树高,需要作右平衡处理
Right_Root_Balance(T);
taller=false;
break;
}
}
return1;
}
}
Main函数:
//平衡二叉树.cpp:
定义控制台应用程序的入口点。
//
#include"stdafx.h"
#include"function.h"
int_tmain(intargc,_TCHAR*argv[])
{
system("color9f");
system("modecon:
cols=100lines=40");
intinput,m;
charsearch;
booltaller=false;
intshorter=0;
BTreeT;
T=(BTree)malloc(sizeof(BTNode));
T=NULL;
while
(1)
{
cout<<"\n请选择需要的二叉树操作\n"<cout<<"1.创建二叉树.增加新结点.直接创建平衡二叉树.在平衡二叉树上增加新结点并调平衡.删除.退出\n"<cin>>input;
getchar();
switch(input)
{
case1:
CreatBT(T);
break;
case2:
cout<<"请输入你要增加的关键字"<cin>>search;
getchar();
InsertBT(T,search,taller);
m=0;
PrintBT(T,m);
break;
case3:
Creat_AVL(T);
break;
case4:
cout<<"请输入你要增加的关键字"<cout<getchar();
SetAVL(T,search,taller);
m=0;
PrintBT(T,m);
break;
case5:
cout<<"请输入你要删除的关键字";
scanf("%d",&search);
getchar();
DeleteAVL(T,search,shorter);
m=0;
PrintBT(T,m);
break;
case0:
break;
default:
cout<<"输入错误,请重新选择。
";
break;
}
if(input==0)
break;
cout<<"按任意键继续.";
getchar();
}
return0;
}
Function.h
#include
#include
#include
usingnamespacestd;
//定义树的结点类型
typedefstructBTNode
{
intdata;
intbf;//平衡因子
structBTNode*lchild,*rchild;//左、右孩子
}BTNode,*BTree;
#defineLH+1//LeftHeight左高
#defineEH0//EqualHeight相同的高度
#defineRH-1//RightHeightHigh右高
#defineET(a,b)((a)==(b))//a=b
#defineLT(a,b)((a)<(b))//a
#defineRT(a,b)((a)>(b))//a>b
//需要的函数声明
voidCreatBT(BTree&T);//创建二叉树以#结束
voidRight_Balance(BTree&p);//对*p为根进行右旋转处理
voidLeft_Balance(BTree&p);//对*p为根的进行左旋转处理
voidLeft_Root_Balance(BTree&T);//对*T所指节点为根的二叉树作左旋转调平
voidRight_Root_Balance(BTree&T);//对*T所指结点为根的二叉树作右旋转调平
boolInsertBT(BTree&T,inti,bool&taller);//插入节点,若结点中存在该点则返回值为否则的话voidDelete(BTreeq,BTree&r,int&shorter);//删除某个节点
voidLeft_Root_Balance_det(BTree&p,int&shorter);//删除某个节点进行平衡二叉树左平衡转
voidRight_Root_Balance_det(BTree&p,int&shorter);//删除某个节点进行平衡二叉树右平衡调
intDeleteAVL(BTree&p,intx,int&shorter);//删除整个二叉树
voidCreat_AVL(BTree&T);//直接创建平衡二叉树
boolSetAVL(BTree&T,inti,bool&taller);//二叉树的调平情况分类进行调平函数
voidPrintBT(BTreeT,i