最近学习了一下平衡二叉树。某位同仁对于平衡二叉树的评价“这次那你写一下,就不会再写的代码,可能有人至今还没明白它的意思”很有同感,所以把代码粘贴如下:
void RollRight(BitreeNode *&t)
{
BitreeNode *temp=t->ReturnLeft();
t->ReturnLeft()=temp->ReturnRight();
temp->ReturnRight()=t;
t=temp;
}//单右旋
void RollLeft(BitreeNode *&left)
{
BitreeNode *temp=left->ReturnRight();
left->ReturnRight()=temp->ReturnLeft();
temp->ReturnLeft()=left;
left=temp;
}//单右旋
void RightBalance(BitreeNode *& p)//右平衡的调整
{
BitreeNode *temp1=p->ReturnRight();
BitreeNode *temp2=temp1->ReturnLeft();
switch(temp1->Balance)
{
case 1: //左边高,现在插入在p右孩子的左子树上
switch(temp2->Balance) //要做双旋处理
{
case 1:
p->Balance=0;temp1->Balance=-1;
break;
case 0:
p->Balance=temp1->Balance=0;
break;
case -1:
p->Balance=1;temp1->Balance=0;
break;
}
temp2->Balance=0;
RollRight(p->ReturnRight());//对p的右子树做右旋平衡处理
RollLeft(p);//对p做左旋平衡处理
break;
case -1://右边高,现在插入在p的右孩子的右子树上;需要对p做左旋转
p->Balance=temp1->Balance=0;
RollLeft(p);
}
}
void LeftBalance(BitreeNode *&p)
{
BitreeNode *temp1,*temp2;
temp1=p->ReturnLeft(); //temp1指向*tmp的左子树根结点
switch(temp1->Balance) //检查*tmp的左子树的平衡度,并作相应平衡处理
{
case 1: //新结点插入在*T的左孩子的左子树上,要做单右旋处理
temp1->Balance=p->Balance=0;
RollRight(p);
break;
case -1://新结点插入在p的左孩子的右子树上,要做双旋处理
temp2=temp1->ReturnRight();
switch(temp2->Balance) //修改p及其左孩子的平衡因子
{
case 1:
p->Balance=-1;
temp1->Balance=0;
break;
case 0:
p->Balance=temp1->Balance=0;
break;
case -1:
p->Balance=0;
temp1->Balance=1;
break;
}
temp2->Balance=0;
RollLeft(p->ReturnLeft()); //对p的左子树作左旋平衡处理
RollRight(p); //对p做右旋平衡处理
}
}
调整的函数上面都一样,而对于构建大家就可以各自按照自己的要求建立,有的把查找也写在插入函数里,但以下提供的例子并没有把查找写在里面。
void InsertAverageTree(BitreeNode *&t,int item,bool &flag)//用int型的平衡二叉树插入函数
{
if(t==NULL)
{
t=new BitreeNode(item);//此处可以依据你构建的BitreeNode类,我定义了Int 型的Cost
flag=true;//需要检查平衡度
}
else if (t->Cost<item)
{
InsertAverageTree(t->ReturnRight(),item ,flag);
if(flag)
{
switch(t->Balance) //检查*p的平衡度
{
case 1:
t->Balance=0; //原本左子树比右子树高,现左右子树等高
flag=false;
break;
case 0:
t->Balance=-1; //原本左右子树等高,现因右子树增高而使树增高
flag=true;
break;
case -1:
RightBalance(t); //原本右子树比左子树高,需要做右平衡处理
flag=false;
break;
}
}
}
else if(t->Cost>item)
{
InsertAverageTree(t->ReturnLeft(),item,name,AuNa,flag);
if(flag)
{
switch(t->Balance) //检查*p的平衡度
{
case 1:
LeftBalance(t); //原本左子树比右子树高,需要做左平衡处理
flag=false;
break;
case 0:
t->Balance=1; //原本左右子树等高,现因左子树增高而使树增高
flag=true;
break;
case -1:
t->Balance=0; //原本右子树比左子树高,现左右子树等高
flag=false;
break;
}
}
}
}