zoukankan      html  css  js  c++  java
  • 平衡二叉树(C语言)

    我觉得这个是最通俗易懂的版本了,,改编自网上,,出处忘了,我完整了他的代码,并把风格改成我的了,,函数实在不喜欢一股脑的全部扔上面,。,,,。

    建议阅读这两篇文章:

    http://www.cnki.net/KCMS/detail/detail.aspx?QueryID=2&CurRec=1&recid=&filename=GWDT201034126&dbname=CJFDN0911&dbcode=CJFR&pr=CJFR2010;CFJD2010;&urlid=&yx=&uid=WEEvREcwSlJHSldRa1FiNlpyakNuRFRyd0tkTUkwazlLWW5tbjYzYXFVV3pDK3pWYjBQN3ZZNjdKQTlVQkpWN3l3PT0=$9A4hF_YAuvQ5obgVAqNKPCYcEjKensW4IQMovwHtwkF4VYPoHbKxJw!!&v=MDAyOTJGeURsVzd2SUlqclBlckc0SDlIUHE0NUhZb1I4ZVgxTHV4WVM3RGgxVDNxVHJXTTFGckNVUkw2ZVplZHE=

    http://www.cnblogs.com/fornever/archive/2011/11/15/2249492.html

    #include<stdio.h>
    #include<stdlib.h>
    #define EH 0            /*等高*/
    #define LH 1            /*左高*/
    #define RH -1            /*右高*/
        
    typedef int ElemType;                 /*数据类型*/
    
    typedef struct BiTree{
        ElemType data;                    /*数据元素*/
        int BF;                         /*平衡因子*/
        struct BiTree *lchild,*rchild;     /*左右子女指针*/
    }*Bitree,BitreeNode;
    
    
    int InsertAVL(Bitree *T,ElemType e,bool *taller);
    void LeftBalance(Bitree *T);
    void RightBalance(Bitree *T);
    void R_Rotate(Bitree *T);
    void L_Rotate(Bitree *T);
    bool *taller=(bool*)malloc(sizeof(bool));
    
    int main(void)
    {
        int data;
        Bitree T=NULL;
        while(1)
        {
            printf("enter the number(zero to exit):");
            scanf("%d",&data);
            if(0==data)break;
            InsertAVL(&T,data,taller);
            
        }
        
        
        
        return 0;
    }
    
    
    /*若在平衡的二叉排序树T 中不存在和e 有相同关键码的结点,则插入一个数据元素为e 的*/
    /*新结点,并反回1,否则反回0。若因插入而使二叉排序树失去平衡,则作平衡旋转处理,*/        
    /*布尔型变量taller 反映T 长高与否*/    
    int InsertAVL(Bitree *T,ElemType e,bool *taller)
    {
        if(!*T)                /*插入新结点,树“长高”,置taller 为TURE*/
        {
            (*T)=(Bitree)malloc(sizeof(BitreeNode));
            (*T)->data = e;
            (*T)->lchild = (*T)->rchild = NULL;
            (*T)->BF = EH;
            *taller = true;
        }
        else
        {
            if(e==(*T)->data)        /*树中存在和e 有相同关键码的结点,不插入*/
            {
                *taller = false;
                return 0;
            }    
            if(e<(*T)->data)
            {
                if(!InsertAVL(&(*T)->lchild,e,taller))    return 0;  /*未插入*/
                if(*taller)
                switch((*T)->BF)
                {    
                    case EH :                    /*原本左、右子树等高,因左子树增高使树增高*/
                        (*T)->BF=LH;
                        *taller=true;
                        break;
                    
                    case LH :                    /*原本左子树高,需作左平衡处理*/
                        LeftBalance(T);
                        *taller=false;
                        break;
                    
                    case RH :                    /*原本右子树高,使左、右子树等高*/
                        (*T)->BF=EH; 
                        *taller=false;
                        break;
                        
                }
                
            }
            else
            {
                if(!InsertAVL(&(*T)->rchild,e,taller))    return 0;  /*未插入*/
                if(*taller)
                switch((*T)->BF)
                {    
                    case EH :                    /*原本左、右子树等高,因右子树增高使树增高*/
                        (*T)->BF=RH;
                        *taller=true;
                        break;
                    
                    case LH :                    /*原本左子树高,使左、右子树等高*/
                        (*T)->BF=EH; 
                         *taller=false;
                         break;
                    
                    case RH :                    /*原本右子树高,需作右平衡处理*/
                        RightBalance(T);
                        *taller=false;
                         break;
                        
                }
            }
        }
        return 1;
    }
    
    
    
    /*对以*p 指向的结点为根的子树,作左平衡旋转处理,处理之后,*p 指向的结点为子树的新根*/
    void LeftBalance(Bitree *T)
    {
        Bitree L=(*T)->lchild,Lr;             /*L 指向*T左子树根结点*/
        switch(L->BF)                /*检查L 平衡度,并作相应处理*/
        {
            case LH:                    /*新结点插在*p 左子树的左子树上,需作单右旋转处理*/
                (*T)->BF=L->BF=EH;
                 R_Rotate(T);
                 break;
            case EH:             /*原本左、右子树等高,因左子树增高使树增高*/
                (*T)->BF=LH;    //这里的EH好像没有写的必要 
                  *taller=true;
                  break;
            case RH:                     /*新结点插在*T 左孩子的右子树上,需作先左后右双旋处理*/
                Lr=L->rchild;             /*Lr 指向*p 左孩子的右子树根结点*/    
                switch(Lr->BF)         /*修正*T 及其左子树的平衡因子*/
                {
                    case LH:
                        (*T)->BF = RH;
                        L->BF = EH;
                        break;
                    case EH:
                        (*T)->BF = L->BF= EH;
                        break;
                    case RH:
                        (*T)->BF = EH;
                        L->BF = LH;
                        break;
                    
                }
                Lr->BF = EH;
                L_Rotate(&L);        /*对*T 的左子树作左旋转处理*/
                R_Rotate(T);        /*对*T 作右旋转处理*/
        }
    }
    //这里和leftbalance一个道理,试着自己写一下 
    void RightBalance(Bitree *T)
    {
        Bitree Lr= (*T)->rchild,L;
        switch(Lr->BF)
        {
            case EH:
                *taller = true;
                (*T)->BF = RH;
                break;
            case RH:
                (*T)->BF=Lr->BF=EH;
                L_Rotate(T);
                break;
            case LH:
                L = Lr->lchild;
                switch(L->BF)
                {
                    case EH:
                        (*T)->BF=Lr->BF= EH;
                        break;
                    case RH:
                        Lr->BF= EH;
                        (*T)->BF = LH;
                        break;
                    case LH:
                        (*T)->BF = LH;
                        Lr->BF = EH;
                        break;
                    
                }
                L->BF = EH;
                R_Rotate(&Lr);        
                L_Rotate(T);    
            
        }
    }
    
    
    /*对以*T 指向的结点为根的子树,作右单旋转处理,处理之后,*T 指向的结点为子树的新根*/
    void R_Rotate(Bitree *T)
    { 
        Bitree L=(*T)->lchild;                 /*L 指向*T 左子树根结点*/
        (*T)->lchild=L->rchild;                 /*L 的右子树挂接*T 的左子树*/
        L->rchild=*T; *T=L;             /* *L 指向新的根结点*/
    }
    
    
    /*对以*p 指向的结点为根的子树,作左单旋转处理,处理之后,*p 指向的结点为子树的新根*/
    void L_Rotate(Bitree *T)
    { 
        Bitree Lr=(*T)->rchild;                 /*Lr 指向*T 右子树根结点*/
        (*T)->rchild=Lr->lchild;                 /*L 的左子树挂接*p 的右子树*/
        Lr->lchild=*T; 
        *T=Lr;                                     /* *L 指向新的根结点*/
    }
  • 相关阅读:
    shell 工具函数
    javascript 笔记
    vmware 全屏状态下与宿主机无缝切换
    shell 重定向
    PHP 执行服务器命令的类
    PHP 生成 Html
    PHP 打印输出调试类
    PHP 自动加载类
    getopt 示例
    linux alias 命令别名并输出其原始命令
  • 原文地址:https://www.cnblogs.com/You0/p/4459719.html
Copyright © 2011-2022 走看看