AVL树的概念以及代码实现

中国大学MOOC-陈越、何钦铭-数据结构

跳过概念,直接看代码(不知道怎么做页内跳转,逃ε=ε=ε

  • RR旋转(右单旋)

    破坏节点在发现节点的右子树的右子树上
    破坏节点:插入此节点之后开始不平衡。
    发现节点:插入节点后,离破坏节点路径最短的不平衡结点。


    RR旋转
  • LL旋转(左单旋)

    LL旋转
  • LR旋转

LR旋转
  • RL旋转

RL旋转

代码在此

#include <stdio.h>
#include <stdlib.h>
typedef int DataType;
typedef struct AVLTreeNode *AVLTree;
typedef struct AVLTreeNode *SubTree;
typedef struct AVLTreeNode
{
    int height;     /* to calculate balance factor */
    DataType data;
    AVLTree left;
    AVLTree right;
};

AVLTree CreatAVLTree(DataType node);
AVLTree InsertIntoAVL(AVLTree T, DataType node);
int GetHeight(SubTree T);
int Max(int a, int b);

SubTree LLRotate(SubTree T);
SubTree RRRotate(SubTree T);
SubTree LRRotate(SubTree T);
SubTree RLRotate(SubTree T);

int main(int argc, char const *argv[])
{
    int n, i;
    AVLTree T;
    DataType tempNode;

    scanf("%d", &n);
    scanf("%d", &tempNode);
    T = CreatAVLTree(tempNode); /* creat an empty tree */
    /* insert sequence to build a AVL tree */
    for (i = 1; i < n; i++) {
        scanf("%d", &tempNode);
        if (T) {
            T = InsertIntoAVL(T, tempNode);
        }
        else break;
        /* judge the balance of the tree after insertion by the balance factor */
        /* check from the node to root */
    }
    if (T)
        printf("%d", T->data);
    else
        printf("Input Error! You enter a same number \n");      /* it's not necessary */

    return 0;
}

AVLTree CreatAVLTree(DataType node)
{
    AVLTree T;
    T = (AVLTree)malloc(sizeof(struct AVLTreeNode));
    T->height = 1;
    T->data   = node;
    T->left   = NULL;
    T->right  = NULL;
    return T;
}

AVLTree InsertIntoAVL(AVLTree T, DataType node)
{
    if (!T)
        T = CreatAVLTree(node);
    else {
        if (node < T->data) {
            T->left = InsertIntoAVL(T->left, node);
            /* it will judge the balance factor from bottom to the top */
            if (GetHeight(T->left) - GetHeight(T->right) == 2) {
                if (node < T->left->data)
                    T = LLRotate(T);
                /* it means the node on the current subtree's left subtree 'left */
                else
                    T = LRRotate(T);
            }
        }
        else if (node > T->data) {
            T->right = InsertIntoAVL(T->right, node);
            if (GetHeight(T->right) - GetHeight(T->left) == 2) {
                if (node > T->right->data)
                    T = RRRotate(T);
                else
                    T = RLRotate(T);
            }
        }
        else    /* considering the equal situation, but in this case, it's not necessary */
            return NULL;
    }
    /* updata the height of AVLTree from the leaf node to the root after every insert */
    T->height = Max(GetHeight(T->left), GetHeight(T->right)) + 1;

    return T;

}

int GetHeight(SubTree T)
{
    if (!T)
        return 0;
    else
        return T->height;
}

int Max(int a, int b)
{
    return (a > b) ? a : b;
}

SubTree LLRotate(SubTree T)
{
    SubTree Tmp;
    Tmp = T;
    T = T->left;
    Tmp->left = T->right;
    T->right  = Tmp;
    Tmp->height = Max(GetHeight(Tmp->left), GetHeight(Tmp->right)) + 1;
    T->height   = Max(GetHeight(T->left), GetHeight(T->right)) + 1;
    return T;
}

SubTree RRRotate(SubTree T)
{
    SubTree Tmp;
    Tmp = T;
    T = T->right;
    Tmp->right = T->left;
    T->left    = Tmp;
    Tmp->height = Max(GetHeight(Tmp->left), GetHeight(Tmp->right)) + 1;
    T->height   = Max(GetHeight(T->left), GetHeight(T->right)) + 1;
    return T;
}

SubTree LRRotate(SubTree T)
{
    T->left = RRRotate(T->left);
    T = LLRotate(T);
    return T;
}

SubTree RLRotate(SubTree T)
{
    T->right = LLRotate(T->right);
    T = RRRotate(T);
    return T;
}

/*SubTree LRRotate(SubTree T)
{
    SubTree Tmp;
    Tmp = T;
    T = T->left->right;
    Tmp->left->right = T->left;
    T->left   = Tmp->left;
    Tmp->left = T->right;
    T->right  = Tmp;
    Tmp->height = Max(GetHeight(Tmp->left), GetHeight(Tmp->right)) + 1;
    T->height = Max(GetHeight(T->left), GetHeight(T->right)) + 1;
    return T;
}*/
  • LR旋转可以转换成发现者的左子树 T->left 先做 RR旋转,然后发现者再做LL旋转。
    下面即为一个例子
    8为发现者,4为破坏者。
    LR旋转例子
  • 发现者的左子树 T->left 先做 RR旋转


    T->left做LL旋转
  • 发现者再做LL旋转
    发现者做LL旋转

    本文完
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • AVL树的左旋与右旋等操作 LL旋转: 导致失衡的是节点node的左子树的左孩子,称为LL 调整算法如下:对于节点...
    qratosone阅读 810评论 0 0
  • 1. AVL树 AVL树简单来说是带有平衡条件的二叉查找树.传统来说是其每个节点的左子树和右子树的高度最多差1(注...
    fredal阅读 1,790评论 0 4
  • 一直以来,我都很少使用也避免使用到树和图,总觉得它们神秘而又复杂,但是树在一些运算和查找中也不可避免的要使用到,那...
    24K男阅读 6,660评论 5 14
  • AVL树是带有平衡条件的查找二叉树。这个平衡条件要容易保持,而且他要保证树的深度为O(logN) 原文地址:htt...
    喵了个呜s阅读 7,105评论 0 12
  • 本科就读哲学系的我从来没有过关于宇宙的思考,身为文科生的我对物理学方面从未有过丝毫兴趣,但是看完《三体》的我,白天...
    北风殷殷阅读 2,563评论 20 4