AVL树

来源:互联网 发布:逃生剧情解析 知乎 编辑:程序博客网 时间:2024/06/04 20:15

AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。

这里写图片描述

AVL树中进行插入或删除节点后,可能导致AVL树失去平衡。这种失去平衡的可以概括为4种姿态:LL(左左),LR(左右),RR(右右)和RL(右左)。

LL : 左侧深度高
RR : 右侧深度高
LR : 根的左子树的高度比根的右子树的高度深
RL : 根的右子树的高度比根的左子树的高度深

struct AVL;typedef struct AVL *T;typedef int Instead_Int;struct AVL{    Instead_Int Instead;    int hight;    T Left;    T Right;    AVL() : hight(0), Left(NULL), Right(NULL) {}};

这里写图片描述

这是RR的可能

将节点 v1 右侧的节点保存为 v2, 将 v1 插入到 v2 的左侧, 实现平衡

T Right_One(T avl){    T cpy_avl = avl->Right;    avl->Right = cpy_avl->Left;    cpy_avl->Left = avl;    cpy_avl->hight = Max(Hight(cpy_avl->Right), Max(Hight(avl->Right), Hight(avl->Left)) + 1) + 1;    return cpy_avl;}

同理LL

T Left_One(T avl){    T cpy_avl = avl->Left;    avl->Left = cpy_avl->Right;    cpy_avl->Right = avl;    avl->hight = Max(Hight(avl->Right), Hight(avl->Left)) + 1;    cpy_avl->hight = Max(Hight(cpy_avl->Left), avl->hight) + 1;    return cpy_avl;}

这里写图片描述
这里写图片描述

LR的旋转, 只需要将其先RR 的方式旋转, 在LL方式旋转即可

这里写图片描述

T Left_Two(T avl){    avl->Left = Right_One(avl->Left);    return Left_One(avl);}

RL也同理

T Right_Two(T avl){    avl->Right = Left_One(avl->Right);    return Right_One(avl);}

在插入与删除,都与查询二叉树是一样的, 只有在部分上有点区别, 这是为了保证二叉树的平衡, 即AVL树

//插入T Insert(T avl, Instead_Int insert){    if (avl == NULL)    {        avl = new AVL;        avl->Instead = insert;    }    else        if (avl->Instead > insert)        {            avl->Left = Insert(avl->Left, insert);            //当不保持平衡时, 进入            if (Hight(avl->Left) - Hight(avl->Right) >= 2)            //LL还是LR进行判断                if (avl->Left->Instead > insert)                    avl = Left_One(avl);                else                    avl = Left_Two(avl);        }        else if (avl->Instead < insert)        {            avl->Right = Insert(avl->Right, insert);            if (Hight(avl->Right) - Hight(avl->Left) >= 2)            //RR还是RL进行判断                if (avl->Right->Instead < insert)                    avl = Right_One(avl);                else                    avl = Right_Two(avl);        }    avl->hight = Max(Hight(avl->Right), Hight(avl->Left)) + 1;    return avl;}

源代码

#include <stdlib.h>#include <stdio.h>struct AVL;typedef struct AVL *T;typedef int Instead_Int;struct AVL{    Instead_Int Instead;    int hight;    T Left;    T Right;    AVL() : hight(0), Left(NULL), Right(NULL) {}};#define Max(a, b) (a > b ? a : b)T Insert(T avl, Instead_Int inset);T Dele(T avl, Instead_Int dele);T Left_One(T avl);T Right_One(T avl);T Left_Two(T avl);T Right_Two(T avl);T Find_Max(T avl);T Find_Min(T avl);T Find(T avl, Instead_Int find);void Print(T avl);int Hight(T avl);int main(){    T avl = NULL;    for (int i = 0; i < 10; i++)        avl = Insert(avl, i + 1);    avl = Dele(avl, 5);    Print(avl);    system("pause");    return 0;}T Find_Min(T avl){    if (avl == NULL)        return NULL;    if (avl->Left == NULL)        return avl;    else        Find_Min(avl->Left);}T Find_Max(T avl){    if (avl == NULL)        return NULL;    while (avl->Right != NULL)        Find_Max(avl->Right);    return avl;}int Hight(T avl){    if (avl == NULL)        return -1;    else        return avl->hight;}//LLT Left_One(T avl){    T cpy_avl = avl->Left;    avl->Left = cpy_avl->Right;    cpy_avl->Right = avl;    avl->hight = Max(Hight(avl->Right), Hight(avl->Left)) + 1;    cpy_avl->hight = Max(Hight(cpy_avl->Left), avl->hight) + 1;    return cpy_avl;}//RRT Right_One(T avl){    T cpy_avl = avl->Right;    avl->Right = cpy_avl->Left;    cpy_avl->Left = avl;    cpy_avl->hight = Max(Hight(cpy_avl->Right), Max(Hight(avl->Right), Hight(avl->Left)) + 1) + 1;    return cpy_avl;}//LRT Left_Two(T avl){    avl->Left = Right_One(avl->Left);    return Left_One(avl);}//RLT Right_Two(T avl){    avl->Right = Left_One(avl->Right);    return Right_One(avl);}//插入T Insert(T avl, Instead_Int insert){    if (avl == NULL)    {        avl = new AVL;        avl->Instead = insert;    }    else        if (avl->Instead > insert)        {            avl->Left = Insert(avl->Left, insert);            if (Hight(avl->Left) - Hight(avl->Right) >= 2)                if (avl->Left->Instead > insert)                    avl = Left_One(avl);                else                    avl = Left_Two(avl);        }        else if (avl->Instead < insert)        {            avl->Right = Insert(avl->Right, insert);            if (Hight(avl->Right) - Hight(avl->Left) >= 2)                if (avl->Right->Instead < insert)                    avl = Right_One(avl);                else                    avl = Right_Two(avl);        }    avl->hight = Max(Hight(avl->Right), Hight(avl->Left)) + 1;    return avl;}T Dele(T avl, Instead_Int dele){    T cpy_avl = NULL;    if (avl == NULL)    {        avl = new AVL;        avl->Instead = dele;    }    else        if (avl->Instead > dele)        {            avl->Left = Dele(avl->Left, dele);            if (Hight(avl->Left) - Hight(avl->Right) >= 2)                if (avl->Left->Instead > dele)                    avl = Left_One(avl);                else                    avl = Left_Two(avl);        }        else if (avl->Instead < dele)        {            avl->Right = Dele(avl->Right, dele);            if (Hight(avl->Right) - Hight(avl->Left) >= 2)                if (avl->Right->Instead < dele)                    avl = Right_One(avl);                else                    avl = Right_Two(avl);        }        else if (avl->Left && avl->Right)        {            cpy_avl = new AVL;            cpy_avl = Find_Min(cpy_avl->Right);            avl->Instead = cpy_avl->Instead;            avl->Right = Dele(avl->Right, avl->Instead);        }        else        {            if (avl->Right == NULL)                avl = avl->Left;            else                avl = avl->Right;            free(cpy_avl);        }    return avl;}T Find(T avl, Instead_Int find){    if (avl == NULL)        return NULL;    else if (avl->Instead > find)        avl->Left = Find(avl->Left, find);    else if (avl->Instead < find)        avl->Right = Find(avl->Right, find);    return avl;}void Print(T avl){    if (avl != NULL)    {        printf("%d ", avl->Instead);        Print(avl->Left);        Print(avl->Right);    }}
原创粉丝点击