【数据结构】——平衡二叉树(AVL树)

上一篇文章我们讲述了二叉排序树,然而当我们遇到特殊情况,如a[10] ={3,2,1,4,5,6,7,10,9,8}的情况时完全符合二叉树的定义,但是对这样高度达到8的二叉树老说是非常不利的,所以我们对此引入了一个新的概念——平衡二叉树~

一、什么是平衡二叉树

是一种高度平衡的二叉排序树,其中每一个结点的左子树和右子树的高度差至多等于1 。将二叉树上结点的左子树深度减去右子树深度的值称为平衡因子BF当|BF|>1时,该二叉树是不平衡的。

二、平衡二叉树的实现原理

其构建的基本思想是在构建二叉排序树的过程中,每当插入一个结点时,先检查是否因插入而破坏了树的平衡性,若是,找出最小不平衡子树。在保持二叉排序树的前提下,调整最小不平衡子树中各结点之间的连接关系,进行相应的旋转,使之成为新的平衡子树。

最小不平衡子树:
在这里插入图片描述
1、最小不平衡子树的调整有三种情况

  1. 当BF > 1时,对整个树进行右旋(顺时针)旋转
  2. 当BF < 1时,对整个树进行左旋
  3. 当遇到BF的值相反的时,先进行一次使符号相同的旋转,再反向旋转一次。

2、实现算法:
结点结构:

typedef struct BiTNode
{
    int bf;//用来存储平衡因子
    int data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

右旋操作

void R_Rotate(BiTree *p)
{
    BiTree L;
    L = (*P)->lchid;
    (*P) -> lchid = L->rchild;
    L->rchid = (*p);
    *p = L;
}

在这里插入图片描述
左旋操作

void L_Rotate(BiTree *p)
{
    BiTree R;
    R = (*P)->rchid;
    (*P) -> rchid = R->lchild;
    R->lchid = (*p);
    *p = R;
}

左平衡旋转处理函数代码:

对以指针T所指结点为根的二叉树作左平衡旋转处理,本算法结束时,指针T指向新的根结点
函数被调用,传入一个需调整平衡性的子树T,该函数被调用时其实已经确认当前子树是不平衡状态,此时T的根结点应该是平衡因子BF大于1的数。

#define LH 1 //左高
#define EH 0 //等高
#define RH -1//右高
void LeftBalance(BiTree *T)
{
    BiTree L,Lr;
    L = (*T) -> lchild;//L指向T的左子树根结点
    switch(L->bf)
    {
        //检查T的左子树的平衡度,并作相应的平衡处理
        case LH://新结点插入组在T的左孩子的左子树上,要做右单璇处理
            (*T)->bf = L->bf = EH;
            R_Rotate(T);
            break;
        case RH:新结点插入组在T的左孩子的右子树上,要做双璇处理
            Lr = L->rchild;
            switch(Lr->bf)
            {
                case LH:
                    (*T)->bf = RH;
                    L->bf = EH;
                    break;
                case EH:
                    (*T)->bf = EH;
                    L->bf = LH;
                    break;
                case RH:
                    (*T)->bf = EH;
                    L->bf = LH;
                    break;
            }
        Lr->bf = EH;
        L_Rotate(&(*T)->lchid);//对T的左子树作左旋平衡处理
        R_Rotate(T);//对T作右旋平衡处理
    }
}

右平衡旋转处理同上做细微变化就行,在此不予阐述

主函数代码:

Status InsertAVL(BiTree * T,int e,Status *taller)
{
    if(!*T)
    {
        //插入新结点,树“长高”,置taller为true
        *T = (BiTree)malloc(sizeof(BiTNode));
        (*T)->data = e;
        (*T)->lchid = (*T)->rchid=null;
        (*T)->bf = EH;
        *taller = ture;
    }
    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 = fales;
                        break;
                    case EH://原本左右子树等高,现因左子树增高而树
                        (*T)->bf = LH;
                        *taller = ture;
                        break;
                    case RH://原本右子树比左子树高,现在左右子树等高
                        (*T)->bf = EH;
                        *taller = fales;
                        break;
                }
            }
        }
        else
        {//应继续在T的右子树中进行搜索
            if(!InsertAVL(&(*T)->lchild,e,taller))//未插入
                return false;
            if(taller)//已插入到T的右子树中且右子树“长高”
            {
                switch((*T)->bf)//检查T的平衡度
                {
                    case LH://原本左子树比右子树高,现在左右子树等高
                        (*T)->bf = EH;
                        *taller = fales;
                        break;
                    case EH://原本左右子树等高,现因右子树增高而树
                        (*T)->bf = RH;
                        *taller = ture;
                        break;
                    case RH://原本右子树比左子树高,需要进行做平衡处理
                        RightBalance(T);
                        *taller = fales;
                        break;
                }
            }   
        }
    }
    return ture;
}

验证代码:
在这里插入图片描述
插入、删除、查找的时间复杂度都是O(logn)

发布了62 篇原创文章 · 获赞 7 · 访问量 2576

猜你喜欢

转载自blog.csdn.net/qq_43412060/article/details/104399940