C++数据结构-平衡二叉树AVL的构建,插入和调整

#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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43323201/article/details/84921453