平衡二叉树

来源:互联网 发布:用友软件经销商查询 编辑:程序博客网 时间:2024/06/04 19:05
#include<stdio.h>#include<stdlib.h>#include<string.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define LH +1 #define EH 0 #define RH -1typedef int Status;typedef int ElemType;typedef struct BSTNode{ElemType data;int bf;struct BSTNode *lchild ,*rchild;} BSTNode,* BSTree; /*查找算法*/Status SearchBST(BSTree T,ElemType e);//查找void R_Rotate(BSTree &p);//右旋void L_Rotate(BSTree &p);//左旋void LeftBalance(BSTree &T);//插入平衡调整void RightBalance(BSTree &T);//插入平衡调整Status InsertAVL(BSTree &T,ElemType e,int &taller);//插入void DELeftBalance(BSTree &T);//删除平衡调整void DERightBalance(BSTree &T);//删除平衡调整Status Delete(BSTree &T,int &shorter);//删除操作Status DeleteAVL(BSTree &T,ElemType e,int &shorter);//删除操作void PrintBSTree(BSTree &T,int lev);//凹入表显示Status SearchBST(BSTree T,ElemType e){if(!T){return FALSE; //查找失败}else if(e == T->data ){return TRUE; //查找成功}else if (e < T->data){return SearchBST(T->lchild,e);  //递归调用}else{return SearchBST(T->rchild,e);  //递归调用}}//右旋void R_Rotate(BSTree &p){BSTree lc;                         lc = p->lchild;p->lchild = lc->rchild;lc->rchild = p;p = lc;}//左旋void L_Rotate(BSTree &p){BSTree rc;rc = p->rchild;p->rchild = rc->lchild; rc->lchild = p;p = rc;} //左插入平衡调整void LeftBalance(BSTree &T){BSTree lc,rd; lc=T->lchild;switch(lc->bf){ case LH:                      T->bf = lc->bf=EH; R_Rotate(T);break; case RH:           rd=lc->rchild; switch(rd->bf){ case LH: T->bf=RH; lc->bf=EH; break; case EH: T->bf=lc->bf=EH; break; case RH: T->bf=EH; lc->bf=LH; break; } rd->bf=EH; L_Rotate(T->lchild); R_Rotate(T);} }//  右插入平衡调整void RightBalance(BSTree &T) { BSTree rc,ld; rc=T->rchild; switch(rc->bf){ case RH:                      //左旋T->bf= rc->bf=EH; L_Rotate(T); break; case LH:                    //ld=rc->lchild; switch(ld->bf){ case LH: T->bf=RH; rc->bf=EH; //插入结点无兄弟结点,且新节点从他的左边break; case EH: T->bf=rc->bf=EH;   //插入结点有兄弟结点break; case RH: T->bf = EH; rc->bf=LH; //插入结点无兄弟结点,且新节点从他的右边break; } ld->bf=EH; R_Rotate(T->rchild); L_Rotate(T); } } //插入结点Status InsertAVL(BSTree &T,ElemType e,int &taller){if(!T){T= (BSTree) malloc (sizeof(BSTNode));T->data = e;T->lchild = T->rchild = NULL;T->bf = EH;taller = 1;      // taller表示树是否"长高"} else{if(e == T->data){taller = 0;printf("请插入不同的数值\n");return ERROR;}if(e < T->data){   if(!InsertAVL(T->lchild,e,taller))//递归调用 找到父节点,判断左孩子是否为空   return ERROR;   if(taller)   switch(T->bf){   case LH:   LeftBalance(T);   taller = 0;   break;   case EH :   T->bf = LH;   taller = TRUE;   break;   case RH:   T->bf = EH;   taller = FALSE;   break;   }}else{    if (!InsertAVL(T->rchild,e,taller)){     // 递归调用 找到父节点,判断右孩子是否为空return ERROR;}if(taller)switch(T->bf){case LH:T->bf = EH;taller = FALSE;break;case EH:T->bf = RH;taller = TRUE;break;case RH:RightBalance(T);   //右平衡调整taller = FALSE;break;}}}return 1;}//删除左子树结点平衡调整      左右void DELeftBalance(BSTree &T){BSTree lc,rd;   lc=T->lchild;switch(lc->bf){ case LH: T->bf = EH; //lc->bf= EH;R_Rotate(T);break; case EH: T->bf = EH; lc->bf= EH;R_Rotate(T);break; case RH: rd=lc->rchild; switch(rd->bf){ case LH: T->bf=RH; lc->bf=EH; break; case EH: T->bf=lc->bf=EH; break; case RH: T->bf=EH; lc->bf=LH; break; } rd->bf=EH; L_Rotate(T->lchild); R_Rotate(T);} }//删除右子树结点平衡调整   void DERightBalance(BSTree &T) { BSTree rc,ld; rc=T->rchild; switch(rc->bf){ case RH: T->bf= EH; //rc->bf= EH;L_Rotate(T); break;case EH:T->bf= EH; //rc->bf= EH;L_Rotate(T); break;case LH: ld=rc->lchild; switch(ld->bf){ case LH: T->bf=RH; rc->bf=EH; break; case EH: T->bf=rc->bf=EH; break; case RH: T->bf = EH; rc->bf=LH; break; } ld->bf=EH; R_Rotate(T->rchild); L_Rotate(T); } } //被删的节点既有左子树又有右子树void SDelete(BSTree &T,BSTree &q,BSTree &s,int &shorter){    if(s->rchild){    SDelete(T,s,s->rchild,shorter);  //被删除结点最右边结点if(shorter)switch(s->bf){case EH:s->bf = LH;shorter = 0;break;case RH:s->bf = EH;shorter = 1;break;case LH:DELeftBalance(s);shorter = 0;break;}return;}T->data = s->data;if(q != T)q->rchild = s->lchild;elseq->lchild = s->lchild;shorter = 1;}//删除结点Status Delete(BSTree &T,int &shorter){BSTree q;if(!T->rchild){       //被删的节点只有左子树,其父节点直接指向左孩子  叶子节点也是这q = T;T = T->lchild;free(q);shorter = 1;   }else if(!T->lchild){       //被删的节点只有右子树,其父节点直接指向右孩子 叶子节点也是这q = T;T= T->rchild;free(q);shorter = 1;}else{SDelete(T,T,T->lchild,shorter);    //被删的节点有左右子树if(shorter)                        //进行平衡调整switch(T->bf){case EH:T->bf = RH;shorter = 0;break;case LH:T->bf = EH;shorter = 1;break;case RH:DERightBalance(T);shorter = 0;break;}}return TRUE;}//删除操作  找结点Status DeleteAVL(BSTree &T,ElemType e,int &shorter){int sign = 0;if (!T){return sign;}else{if(e == T->data){sign = Delete(T,shorter);return sign;}else if(e < T->data){            //向左查找sign = DeleteAVL(T->lchild,e,shorter);if(shorter)         //通过shorter回溯switch(T->bf){case EH:T->bf = RH;shorter = 0;break;case LH:T->bf = EH;shorter = 1;break;case RH:DERightBalance(T);shorter = 0;break;}return sign;}else{                                //向右查找sign = DeleteAVL(T->rchild,e,shorter);if(shorter)     //通过shorter回溯switch(T->bf){case EH:T->bf = LH;shorter = 0;break;case RH:T->bf = EH;break;case LH:DELeftBalance(T);shorter = 0;break;}return sign;}}}//构建void CreatBSTree(BSTree &T){FILE *fp;    if((fp=fopen("a.txt", "r"))==NULL)    {        printf("can't open the file!\n");        exit(0);        } int e,taller = 0;//printf("输入结点个数:");//scanf("%d",&num);//printf("请顺序输入结点值:\n");//for(i = 0 ;i < num;i++){//printf("第%d个结点的值:",i+1);while(feof(fp)==0){    fscanf(fp,"%d",&e);    InsertAVL(T,e,taller) ;}//scanf("%d",&e);//}printf("构建成功,输入任意字符返回\n");getchar();getchar();fclose(fp);}//凹入表形式显示方法void PrintBSTree(BSTree &T,int lev){int i;if(T->rchild)PrintBSTree(T->rchild,lev+1);for(i = 0;i < lev;i++)printf(" ");printf("%d\n",T->data);if(T->lchild)PrintBSTree(T->lchild,lev+1);}void main(){BSTree T1 = NULL;int cho,taller,e,k;taller = 0;k = 0;while(1){printf(" 平衡二叉树操作的演示\n");printf("******************************************************************************/n");printf(" 平衡二叉树显示区 \n");printf("T1树\n");if(!T1 )printf(" 当前为空树\n");else{PrintBSTree(T1,1);}printf("******************************************************************************\n");printf("T1操作:1.创建 2.插入 3.查找 4.删除 \n");printf("0.退出\n");printf("******************************************************************************\n");printf("输入你要进行的操作:");scanf("%d",&cho);switch(cho){case 1:     CreatBSTree(T1);    break;case 2:printf("请输入要插入关键字的值");scanf("%d",&e);InsertAVL(T1,e,taller) ;break;case 3:printf("请输入要查找关键字的值");scanf("%d",&e);if(SearchBST(T1,e))printf("查找成功!\n");elseprintf("查找失败!\n");printf("按任意键返回");getchar();getchar();break;case 4:printf("请输入要删除关键字的值");scanf("%d",&e);if(DeleteAVL(T1,e,k))printf("删除成功!\n");elseprintf("删除失败!\n");printf("按任意键返回");getchar();getchar();break;case 0://system("cls");exit(0);}}}

#include<iostream>#include<fstream>#include<malloc.h>//malloc()using namespace std;#define  LH 1//左高#define  EH 0//等高#define  RH -1//右高typedef struct TreeNode{    int m_nValue;//学号,检测该学号的学生是不是存在    int BF;//平衡因子    TreeNode *lchild;    TreeNode *rchild;}*PBSTree;class AVLTree{protected:    int len;//树高,GetHeight    int BF;//平衡因子    TreeNode *lc,*rd;    PBSTree rc,ld;    TreeNode *p;    PBSTree q;public:    PBSTree root;    AVLTree()    {        PBSTree root=NULL;    };    ~AVLTree() {};    void Instree(PBSTree root,int m_nValue);//插入节点    void PreTraver(PBSTree root);//先序遍历    void InorderTra(PBSTree root);//中序遍历    void RR_Rotate(PBSTree r);//右旋转处理    int GetHeight(PBSTree root);//获得树的高度    int GetBF(PBSTree root);//获得树的平衡因子    void LL_Rotate(PBSTree r);//左旋转处理    void RL_Rotate(PBSTree r);//先右旋转,再左旋转    void LR_Rotate(PBSTree r);//先左旋转,再右旋转    void LeftBalance(PBSTree T);//左平衡处理    void RightBalance(PBSTree T);//右平衡处理    bool FindNode(PBSTree T,int e);//查找节点    void DELeftBalance(PBSTree T);//删除平衡 左    void DERightBalance(PBSTree T);//删除平衡  右    void SDelete(PBSTree T,PBSTree q,PBSTree s,int shorter);//被删的节点有左右子树    int Delete(PBSTree T,int shorter);//执行删除    int DeleteAVL(PBSTree T,int e,int shorter);//删除操作入口函数,为了找到要删的节点};int Max(int a,int b){    if(a>b)return a;    else return b;}int AVLTree::GetHeight(PBSTree root){    if(root==NULL)len=0;    else    {        len=Max(GetHeight(root->lchild),GetHeight(root->rchild))+1;    }    return len;}void AVLTree::InorderTra(PBSTree root)//中序遍历{    if(root->lchild)        InorderTra(root->lchild);    printf("%d ",root->m_nValue);    if(root->rchild)        InorderTra(root->rchild);}int AVLTree::GetBF(PBSTree root){    BF=GetHeight(root->lchild)-GetHeight(root->rchild);    return BF;}void AVLTree::Instree(PBSTree root,int m_nValue){    if(root==NULL)    {        root=(TreeNode*)malloc(sizeof(TreeNode));        root->m_nValue=m_nValue;        root->lchild=NULL;        root->rchild=NULL;        root->BF=EH;//初始叶子结点的平衡因子为等高    }    else if(m_nValue<root->m_nValue)    {        Instree(root->lchild,m_nValue);        switch(root->BF)//检查root的平衡度        {        case LH://原来树root的左子树比右子树高,现在左子树更高            LeftBalance(root);//对树进行左平衡处理            break;        case EH://原来树root的左右子树等高,现在左子树高            root->BF=LH;//root的平衡因子由0变为1            break;        case RH://原来树root的右子树比左子树高,现在左右子树等高            root->BF=EH;        }    }    else if(m_nValue>root->m_nValue)    {        Instree(root->rchild,m_nValue);        switch(root->BF)        {        case LH:            root->BF=EH;//原来树root的左子树比右子树高,现在root的左右子树等高            break;        case EH://原来树root的左右子树等高,现在root的右子树更高            root->BF=RH;            break;        case RH://原来右子树比左子树高,现在root右子树高            RightBalance(root);//对树root作右平衡处理        }    }}void AVLTree::PreTraver(PBSTree root){    if(root)    {        cout.width(3);        cout<<root->m_nValue;    }    if(root->lchild)        PreTraver(root->lchild);    if(root->rchild)        PreTraver(root->rchild);}void AVLTree::LL_Rotate(PBSTree r)//插入位置为右子树右孩子,要进行左旋转{    //TreeNode *p;    p=r->rchild;//p指向r的右孩子结点    r->rchild=p->lchild;//r结点左旋转成为p的左子树,p原来的左子树成为r的右子树    p->lchild=r;//r成为p的左孩子    r=p;}void AVLTree::RR_Rotate(PBSTree r)//插入位置为左子树左孩子,进行右旋转{    //TreeNode *p;    p=r->lchild;    r->lchild=p->rchild;    p->rchild=r;    r=p;}void AVLTree::RL_Rotate(PBSTree r)//插入位置为右子树左孩子,先进行右旋转,再进行左旋转{    // TreeNode *p;    p=r->rchild;    RR_Rotate(p);//最小失衡树的根结点的右子树根结点进行右旋转    r->rchild=p;//更新最小失衡树根结点的右孩子    LL_Rotate(r);//最小失衡树的根结点进行左旋转}void AVLTree::LR_Rotate(PBSTree r)//插入位置为左子树右孩子,先进行左旋转,再进行右旋转{    // TreeNode *p;    p=r->lchild;    LL_Rotate(p);//最小失衡树根结点的左子树根结点进行左旋转    r->lchild=p;//更新最小失衡树根结点的左孩子    RR_Rotate(r);//最小失衡树根结点进行右旋转}void AVLTree::LeftBalance(PBSTree T)//左平衡处理{    //初始条件:原来平衡的二叉排序树T的左子树比右子树高(T->BF=1)//          又在左子树中插入了结点,并导致左子树更高,破坏了树T的平衡性//操作结果:对不平衡的树T作左平衡旋转处理,使树T的重心右移实现 新的平衡    //TreeNode *lc,*rd;    lc=T->lchild;//lc指向T的左孩子结点    switch(lc->BF)//检查T左子树的平衡因子    {    case LH://新结点插入在T的左孩子的左子树上,导致左子树的平衡因子为左高,进行右旋转处理        RR_Rotate(T);//右旋转处理        T->BF=lc->BF=EH;//旋转后,原根结点和左孩子结点平衡因子都 为0        break;    case RH://新结点插入在T的左孩子的右子树上,导致左子树的平衡因子为右高,进行LR处理        rd=lc->rchild;        switch(rd->BF)        {        case LH://新结点插入在T的左孩子的右子树的左子树上            T->BF=RH;//旋转后,原根结点的平衡因子为右高            lc->BF=EH;//旋转后,原根结点的左孩子结点平衡因子为等高            break;        case EH://新结点插入到T的左孩子的右孩子(叶子)            T->BF=lc->BF=EH;//旋转后,原根和左孩子结点的平衡因子都为等高            break;        case RH://新结点插入在T的左孩子的右子树的右子树上            T->BF=EH;//旋转后,原根结点的平衡因子为等高            lc->BF=LH;//旋转后,原根结点的左孩子结点平衡因子为左高        }        rd->BF=EH;//旋转后的新结点的平衡因子为等高        //双旋转处理        LL_Rotate(T->lchild);//对T的左子树左旋转处理        RR_Rotate(T);//对T作右旋转处理    }}void AVLTree::RightBalance(PBSTree T)//右平衡处理{    //初始条件:原来平衡二叉排序树T的右子树比左子树高,又在右子树中插入结点,导致右子树更高//操作结果:对不平衡的树T作右平衡旋转处理    //TreeNode *rc,*ld;    rc=T->rchild;    switch(rc->BF)    {    case RH://新结点插入在T的右孩子的右子树上,导致右子平衡因子为右高,进行左旋转处理        T->BF=rc->BF=EH;//旋转后,原根结点和右孩子结点的平衡因子均为0        LL_Rotate(T);        break;    case LH://新结点插入在T的右孩子的左子树上,导致右子树的平衡因子为左高,进行双旋处理        ld=rc->lchild;        switch(ld->BF)        {        case RH://新结点插入在T的右孩子的左子树的右子树上            T->BF=LH;//旋转后,原根结点的平衡因子为左高            rc->BF=EH;//旋转后,原根结点的右孩子结点平衡因子为等高            break;        case EH://新结点插入到T的右孩子的左孩子(叶子)            T->BF=rc->BF=EH;//旋转后,原根和右孩子结点的平衡因子等高            break;        case LH://新结点插入到T的右孩子的左子树的左子树            T->BF=EH;//旋转后,原根结点的平衡因子等高            rc->BF=RH;//旋转后,原根结点的右孩子结点的平衡因子为右高        }        ld->BF=EH;//旋转后的新根结点的平衡因子为等高        //双旋转处理        RR_Rotate(T->rchild);//对T的右子树作右旋转处理        LL_Rotate(T);//对T作左旋转处理    }}bool AVLTree::FindNode(PBSTree T,int e)//查找节点{    //右旋    if(!T)    {        return 0; //查找失败    }    else if(e == T->m_nValue )    {        return 1; //查找成功    }    else if (e < T->m_nValue)    {        return FindNode(T->lchild,e);  //递归调用    }    else    {        return FindNode(T->rchild,e);  //递归调用    }}//删除左子树结点平衡调整      左右void AVLTree::DELeftBalance(PBSTree T){    //PBSTree lc,rd;    lc=T->lchild;    switch(lc->BF)    {    case LH:        T->BF= EH;//lc->BF= EH;        RR_Rotate(T);        break;    case EH:        T->BF = EH;        lc->BF= EH;        RR_Rotate(T);        break;    case RH:        rd=lc->rchild;        switch(rd->BF)        {        case LH:            T->BF=RH;            lc->BF=EH;            break;        case EH:            T->BF=lc->BF=EH;            break;        case RH:            T->BF=EH;            lc->BF=LH;            break;        }        rd->BF=EH;        LL_Rotate(T->lchild);        RR_Rotate(T);    }}//删除右子树结点平衡调整void AVLTree::DERightBalance(PBSTree T){    //PBSTree rc,ld;    rc=T->rchild;    switch(rc->BF)    {    case RH:        T->BF= EH;//rc->BF= EH;        LL_Rotate(T);        break;    case EH:        T->BF= EH;//rc->BF= EH;        LL_Rotate(T);        break;    case LH:        ld=rc->lchild;        switch(ld->BF)        {        case LH:            T->BF=RH;            rc->BF=EH;            break;        case EH:            T->BF=rc->BF=EH;            break;        case RH:            T->BF = EH;            rc->BF=LH;            break;        }        ld->BF=EH;        RR_Rotate(T->rchild);        LL_Rotate(T);    }}//被删的节点既有左子树又有右子树void AVLTree::SDelete(PBSTree T,PBSTree q,PBSTree s,int shorter){    if(s->rchild)    {        SDelete(T,s,s->rchild,shorter);  //被删除结点最右边结点        if(shorter)            switch(s->BF)            {            case EH:                s->BF = LH;                shorter = 0;                break;            case RH:                s->BF = EH;                shorter = 1;                break;            case LH:                DELeftBalance(s);                shorter = 0;                break;            }        return;    }    T->m_nValue = s->m_nValue;    if(q != T)        q->rchild = s->lchild;    else        q->lchild = s->lchild;    shorter = 1;}//删除结点int AVLTree::Delete(PBSTree T,int shorter){    //PBSTree q;    if(!T->rchild)        //被删的节点只有左子树,其父节点直接指向左孩子  叶子节点也是这    {        q = T;        T = T->lchild;        free(q);        shorter = 1;    }    else if(!T->lchild)        //被删的节点只有右子树,其父节点直接指向右孩子 叶子节点也是这    {        q = T;        T= T->rchild;        free(q);        shorter = 1;    }    else    {        SDelete(T,T,T->lchild,shorter);    //被删的节点有左右子树        if(shorter)                        //进行平衡调整            switch(T->BF)            {            case EH:                T->BF = RH;                shorter = 0;                break;            case LH:                T->BF = EH;                shorter = 1;                break;            case RH:                DERightBalance(T);                shorter = 0;                break;            }    }    return 1;}//删除操作时寻找结点int AVLTree::DeleteAVL(PBSTree T,int e,int shorter){    int sign = 0;    if (!T)    {        return sign;    }    else    {        if(e == T->m_nValue)//如果找到就执行删除        {            sign = Delete(T,shorter);//如果找到就执行删除            return sign;        }        else if(e < T->m_nValue)             //向左查找        {            sign = DeleteAVL(T->lchild,e,shorter);            if(shorter)         //通过shorter回溯                switch(T->BF)                {                case EH:                    T->BF = RH;                    shorter = 0;                    break;                case LH:                    T->BF = EH;                    shorter = 1;                    break;                case RH:                    DERightBalance(T);                    shorter = 0;                    break;                }            return sign;        }        else                                 //向右查找        {            sign = DeleteAVL(T->rchild,e,shorter);            if(shorter)     //通过shorter回溯                switch(T->BF)                {                case EH:                    T->BF = LH;                    shorter = 0;                    break;                case RH:                    T->BF = EH;                    break;                case LH:                    DELeftBalance(T);                    shorter = 0;                    break;                }            return sign;        }    }}//void AVLTree::AVLTree(){// TreeNode *root=NULL;//}int main(){    AVLTree AVL=AVLTree();    AVL.root=NULL;    int taller,e,k;    char cho;    taller = 0;    k = 0;    while(1)    {        printf("操作:1.创建 2.插入 3.查找 4.删除 5.遍历 0.退出\n");        printf("输入你要进行的操作:");        scanf("%c",&cho);        switch(cho)        {        case '1':        {            FILE *fp;            if((fp=fopen("te.txt", "r"))==NULL)            {                printf("文件打开失败\n");                exit(0);            }            int e = 0;            while(feof(fp)==0)            {                fscanf(fp,"%d",&e);                AVL.Instree(AVL.root,e);            }            AVL.InorderTra(AVL.root);            printf("\n");        }        getchar();        break;        case '2':        {            printf("请输入要插入关键字的值");            scanf("%d",&e);            AVL.Instree(AVL.root,e);            AVL.InorderTra(AVL.root);            printf("\n");        }        getchar();        break;        case '3':        {            printf("请输入要查找关键字的值");            scanf("%d",&e);            if(AVL.FindNode(AVL.root,9))                printf("\n找到\n");            else                printf("\n没有找到\n");            AVL.InorderTra(AVL.root);            printf("\n");            getchar();        }        break;        case '4':            printf("请输入要删除关键字的值");            scanf("%d",&e);            if(AVL.DeleteAVL(AVL.root,e,k))                printf("删除成功!\n");            else                printf("删除失败!\n");            getchar();            break;        case '5':            printf("中序遍历:");            AVL.InorderTra(AVL.root);            printf("\n");            printf("前序遍历:");            AVL.PreTraver(AVL.root);            printf("\n");            getchar();            break;        case '0':            exit(0);        }    }    return 1;}
0 0
原创粉丝点击