数据结构之查找3

平衡二叉树是一种二叉排序树,其中每一个结点左子树和右子树高度差至多等于1。

二叉树左子树深度减去右子树深度的值称为平衡因子。

平衡因子只可能-1、0、1。

距离插入结点最近的,且平衡因子的绝对值大于1的结点的根的子树我们称为最小不平衡子树。

//二叉树的二叉链表结点结构定义
typedef struct BiTNode
{
    int data;
    int bf;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

//对以p为根的二叉排序树作右旋处理
//处理之后p指向新的树根结点,即旋转处理之前的左子树的根结点
void R_Rotate(BiTree *p)
{
    BiTree L;
    L = (*p)->lchild;
    (*p)->lchild = L->rchild;
    L->rchild = (*p);
    *p = L;
}

//对以p为根的二叉排序树作左旋处理
//处理之后p指向新的树根结点,即旋转处理之前的右子树的根结点0
void L_Rotate(BiTree *p)
{
    BiTree R;
    R = (*p)->rchild;
    (*p)->rchild = (*p)->lchild;
    R->lchild = (*p);
    *p = R;
}

#define LH +1       //左高
#define EH 0        //等高
#define RH -1       //右高

//对以指针T所指结点为根的二叉树作作平衡旋转处理
//本算法结束时,指针T指向新的根结点
void LeftBalance(BiTree *T)
{
    BiTree L,Lr;
    L = (*T)->lchild;
    switch(L->bf)
    {
        //检查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)
                    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(&(*T)->lchild);    //对T的左子树作左旋平衡处理
            R_Rotate(T);    //对T作右旋平衡处理
    }
}
//若在平衡的二叉排序树T中不存在和e有相同关键字的结点,则插入一个
//数据元素为e的新结点并返回1,否则返回0,若因插入而使二叉排序树
//失去平衡,则作平衡旋转处理布尔变量taller反映T长高与否。
Status InsertAVL(BiTree *T,int e,Status *taller)
{
    if(!*T)
    {
        //插入新结点,树长高,置taller为TRUE
        *T = (BiTree)malloc(sizeof(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)
        {
            //应继续在T的左子树中进行搜索
            if(!InsertAVL(&(*T)->lchild,e,taller));
                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))
                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;
    }
    
}

多路查找树,其每一个结点的孩子数可以多于两个,且每一个结点处可以存储多个元素。

2-3树是一棵多路查找树:其中的每一个结点都具有两个孩子或三个孩子。

一个2结点包含一个元素和两个孩子(或没有孩子)。

一个3结点包含一大一小两个元素和三个孩子(或没有孩子)。

B树是一种平衡的多路查找树。

结点最大的孩子数目称为B树的阶。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值