#include <iostream>
#define TRUE 1
#define FALSE 0
#define LH 1 //左高
#define EH 0 //等高
#define RH -1 //右高
using namespace std;
typedef int Status;
typedef struct BiTNode
{
int data; //结点数据
int bf ; //结点平衡因子
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
/****************右旋操作*******************/
void R_Rotate(BiTree &p)
{
BiTree L;
L=p->lchild; //L指向p的左子树结点
p->lchild=L->rchild; //L的右子树挂接为p的左子树
L->rchild=p;
p=L; //p指向新的根结点L
}
/****************左旋操作*******************/
void L_Rotate(BiTree &p)
{
BiTree R;
R=p->rchild; //R指向p的右子树结点
p->rchild=R->lchild; //R的左子树挂接为p的右子树
R->lchild=p;
p=R; //p指向新的根结点R
}
/****************左平衡旋转处理*************/
//#define LH 1 //左高
//#define EH 0 //等高
//#define RH -1 //右高
//对以指针T所指结点为根的二叉树做左平衡旋转处理
//本算法结束时,指针T指向新的根结点
void LeftBalance(BiTree &T)
{
BiTree L,Lr;
L=T->lchild; //L指向T的左子树的根节点
switch(L->bf)//L的平衡因子
{ //检查T的左子树的平衡度,并做相应的平衡处理
case LH: //新结点插入在T的左孩子的左子树上,要做单右旋处理
T->bf=L->bf=EH;
R_Rotate(T);
break;
case RH: //新结点插入在T的左孩子的右子树上,要做双旋处理
Lr=L->rchild; //lr指向T的左孩子的右子树根
switch(Lr->bf) //修改T及其左孩子的平衡因子
{
case LH:
T->bf=RH;//-1
L->bf=EH;//0
break;
case EH:
T->bf=L->bf=EH;//0
break;
case RH:
T->bf=EH;
L->bf=LH;
break;
}
Lr->bf=EH;
L_Rotate(T->lchild); //对T的左子树做左旋平衡处理
R_Rotate(T); //对T做右旋平衡处理
}
}
/****************右平衡旋转处理*************/
//对以指针T所指结点为根的二叉树作右平衡旋转处理
//本算法结束时,指针T指向新的根结点
void RightBalance(BiTree &T)
{
BiTree R,Rl;
R=T->rchild; //R指向T的右子树根结点
switch(R->bf)
{//检查T的右子树的平衡度,并作相应平衡处理 */
case RH: /* 新结点插入在T的右孩子的右子树上,要作单左旋处理 */
T->bf=R->bf=EH;
L_Rotate(T);
break;
case LH: /* 新结点插入在T的右孩子的左子树上,要作双旋处理 */
Rl=R->lchild;/*Rl指向T的右孩子的左子树根 */
switch(Rl->bf)
{/* 修改T及其右孩子的平衡因子 */
case RH:
T->bf=LH;
R->bf=EH;
break;
case EH:
T->bf=R->bf=EH;
break;
case LH:
T->bf=EH;
R->bf=RH;
break;
}
Rl->bf=EH;
R_Rotate(T->rchild);/*对T的右子树作右旋平衡处理 */
L_Rotate(T);/*对T作左旋平衡处理 */
}
}
/*****************平衡二叉排序树的插入*****************/
//若在平衡的二叉排序树T中不存在和e有相同的关键字的结点,则插入一个
//数据元素为e的新结点并返回1,否则返回0
//若因插入而使二叉排序树树失去平衡,则作平衡旋转处理
//布尔变量taller反映T长高与否
//返回FALSE表明树没增高,返回TRUE表示树增高
Status InsertAVL(BiTree &T , int e ,Status &taller)
{
if(!T)
{//插入新结点,树“长高”,置taller为TRUE
T=new BiTNode;
T->data=e;
T->lchild=T->rchild=NULL;
T->bf = EH;
taller = TRUE;
}
else
{
if(e == T->data)
{ //树中已存在和e有相同关键字的结点则不再插入
taller=FALSE;
return FALSE;
}
if(e<T->data)
{
if(!InsertAVL(T->lchild,e,taller)) //要是返回TRUE表明树长高了,返回FALSE则表示树没长高
return FALSE; //执行这句代码则表示,没有插入,即在左子树中找到相同的值了
//要是上面那个代码没被执行,则表示插入成功
//此时会逐一递归返回的过程会修改结点的平衡因子和执行下列代码
if(taller) //已插入到T的左子树中,且左子树长高,树要是长高了就可能要调整平衡二叉树
{
switch(T->bf) //检查T的平衡度
{
case LH: //原本左子树比右子树高,需做左平衡处理
LeftBalance(T);
taller = FALSE;
break;
case EH: //原本左右子树等高,现因左子树增高而树增高
T->bf=LH;
taller=TRUE;
break;
case RH: //原本右子树比左子树高,现左右子树等高
T->bf=EH;
taller = FALSE;
break;
}
}
}
else
{ //应继续在T的右子树中进行搜索
if(!InsertAVL(T->rchild,e,taller))//要是返回TRUE表明树长高了,返回FALSE则表示树没长高
return FALSE; //执行这句代码则表示,没有插入,即在左子树中找到相同的值了
//要是上面那个代码没被执行,则表示插入成功
//此时会逐一递归返回的过程会修改结点的平衡因子和执行下列代码
if(taller) //已插到T的右子树,且右子树长高,树要是长高了就可能要调整平衡二叉树
{
switch(T->bf) //检查T的平衡度
{
case LH:
T->bf=EH;
taller = FALSE;
break;
case EH:
T->bf = RH;
taller =TRUE;
break;
case RH:
RightBalance(T); //还未实现
taller = FALSE;
break;
}
}
}
}
return TRUE;
}
/************中序遍历平衡二叉树****************/
//中序遍历输出的结果就是升序排列,验证平衡二叉树是否正确
void InOrderTraverse(BiTree &bt)
{
if(bt == NULL)
cout<<'#';
else
{
InOrderTraverse(bt->lchild);
cout<<bt->data;
InOrderTraverse(bt->rchild);
}
}
int main()
{
int a[10]={3,2,1,4,5,6,7,10,9,8};
BiTree T = NULL ;
Status taller;
//构建平衡二叉树
for(int i=0;i<10;i++)
InsertAVL(T,a[i],taller);
//中序遍历平衡二叉树
InOrderTraverse(T);
return 0;
}
C++数据结构-平衡二叉树AVL的构建,插入和调整
猜你喜欢
转载自blog.csdn.net/weixin_43323201/article/details/84921453
今日推荐
周排行