AVL树的简单实现

本文深入探讨AVL树的概念及其关键操作——左旋和右旋,并提供了详细的代码实现,帮助读者理解如何维持树的平衡。

AVL树是在二叉查找树的基础上加了一个平衡条件,目的是为了防止二叉查找树在某一边的深度过大而使效率降低
AVL树的关键是两个单旋转:左旋转和右旋转
双旋转也就是这两个旋转的组合

旋转的话 用图是最好解释的 下面用从别人那里盗来的图来说明下吧
这里写图片描述

想搞明白的话,自己照着这个图里面的画一画就差不多了

那么下面我就上代码了:

头文件:

#ifndef AVLTREE_H_INCLUDED
#define AVLTREE_H_INCLUDED

struct AvlNode;
typedef struct AvlNode *Position;
typedef struct AvlNode *AvlTree;
typedef double ElementType;
AvlTree MakeEmpty(AvlTree T);
Position Find(ElementType X,AvlTree T);
Position FindMin(AvlTree T);
Position FindMax(AvlTree T);
AvlTree Insert(ElementType X,AvlTree T);
AvlTree Delete(ElementType X,AvlTree T);
ElementType Retrieve(Position P);   //如果是采用懒惰删除,则可以实现这个方法用以恢复

#endif // AVLTREE_H_INCLUDED

实现:

#include "AVLTree.h"
#include <stdio.h>
#include <stdlib.h>

struct AvlNode
{
    ElementType Element;
    AvlTree Left;
    AvlTree Right;
    int Height;
};

static int Height(Position P)
{
    if(P == NULL)
        return -1;
    else
        return P->Height;
}

static int Max(int H1,int H2)
{
    if(H1 > H2)
        return H1;
    else
        return H2;
}

static void FatalError(char * s)
{

}

static void Error(char * s)
{

}

static Position SingleRotateWithLeft(Position K2)
{
    Position K1;

    K1 = K2->Left;
    K2->Left = K1->Right;
    K1->Right = K2;

    K2->Height = Max(Height(K2->Left),Height(K2->Right))+1;

    K1->Height = Max(Height(K1->Left),K2->Height)+1;

    return K1;
}

static Position SingleRotateWithRight(Position K1)
{
    Position K2;

    K2 = K1->Right;
    K1->Right = K2->Left;
    K2->Left = K1;

    K1->Height = Max(Height(K1->Right),Height(K1->Left))+1;
    K2->Height = Max(Height(K2->Right),K1->Height)+1;

    return K2;
}

static Position DoubleRotateWithLeft(Position K3)
{
    K3->Left = SingleRotateWithLeft(K3->Left);

    return SingleRotateWithRight(K3);
}

static Position DoubleRotateWithRight(Position K1)
{
    K1->Right = SingleRotateWithRight(K1->Right);

    return SingleRotateWithLeft(K1);
}

Position Find(ElementType X,AvlTree T)
{
    if(T == NULL)
        return NULL;
    else if(X > T->Element)
        return Find(X,T->Right);
    else if(X < T->Element)
        return Find(X,T->Left);
    else
        return T;
}

Position FindMax(AvlTree T)
{
    if(T != NULL)
        while(T->Right != NULL)
            T = T->Right;
    return T;
}

Position FindMin(AvlTree T)
{
    if(T != NULL)
        while(T->Left != NULL)
            T = T->Left;
    return T;
}

AvlTree Insert(ElementType X,AvlTree T)
{
    if(T == NULL)
    {
        T = malloc(sizeof(struct AvlNode));
        if(T == NULL)
            FatalError("Out of space!!!");
        else
        {
            T->Element = X;
            T->Height = 0;
            T->Left = T->Right = NULL;
        }
      //  printf("%lf\n",T->Element);
    }
    else if(X < T->Element)
    {
        T->Left = Insert(X,T->Left);
        if(Height(T->Left)-Height(T->Right) == 2)
            if(X < T->Left->Element)
                T = SingleRotateWithLeft(T);
            else
                T = DoubleRotateWithRight(T);
    }
    else if(X > T->Element)
    {
        T->Right = Insert(X,T->Right);
        if(Height(T->Right)-Height(T->Left)==2)
            if(X > T->Right->Element)
                T = SingleRotateWithRight(T);
            else
                T = DoubleRotateWithRight(T);
    }
    T->Height = Max(Height(T->Left),Height(T->Right))+1;
    return T;
}

AvlTree Delete(ElementType X,AvlTree T)
{
    Position TmpCell;
    if(T == NULL)
        Error("Element not found");
    else if(X > T->Element)
        Delete(X,T->Right);
    else if(X < T->Element)
        Delete(X,T->Left);
    else if(T->Left && T->Right)
    {
        TmpCell = FindMin(T->Right);
        T->Element = TmpCell->Element;
        T->Right = Delete(T->Element,T->Right);
        T->Height = Max(T->Left->Height,Height(T->Right))+1;
        if(T->Left->Height - T->Right->Height == 2)
        {
            if(T->Left->Left->Height > T->Left->Right->Height)
                SingleRotateWithLeft(T);
            else
                DoubleRotateWithLeft(T);
        }
    }
    else
    {
        TmpCell = T;
        ElementType Tmp;
        if(T->Right == NULL)
            T = T->Left;
        else if(T->Left == NULL)
            T = T->Right;
        free(TmpCell);
        T->Height = (Height(T->Left),Height(T->Right))+1;
    }
    return T;
}

AvlTree MakeEmpty(AvlTree T)
{

}

int main()
{
    AvlTree T = NULL;
    AvlTree T2 = NULL;
    T = Insert(1.01,T);
    Insert(2,T);
    printf("%lf\n",T->Element);
    Position P = FindMax(T);
    printf("%lf\n",P->Element);
    return 0;
}

同样在最后加了一个main函数用于测试,编译器是gcc

PS:代码改编自《数据结构与算法分析第二版》,因为自己在改了一些,所以不保证没有BUG(因为书上的代码是ANSI C,有些用gcc过不了)

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值