AVL树例程

AvlT.h

#ifndef _AvlT_H

struct AvlNode;
typedef struct AvlNode *Position;
typedef struct AvlNode *AvlTree;
typedef int 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

AvlT.c

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

static int Height(Position P);
static int Max(int a, int b);
static Position SingleRotationWithLeft(Position K2);
static Position doubleRotationWithLeft(Position K3);
static Position SingleRotationWithRight(Position K2);
static Position doubleRotationWithRight(Position K3);

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

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

AvlTree MakeEmpty(AvlTree T)
{
    if (T == NULL)
        return NULL;
    else if (T->Left != NULL)
        T->Left = MakeEmpty(T->Left);
    else if (T->Right != NULL)
        T->Right = MakeEmpty(T->Right);

    free(T);

    return T;
}

Position Find(ElementType X, AvlTree T)
{
    if (T == NULL)
    {
        printf("Element is not found!\n");
    }
    else if (X < T->Element)
        return Find(X, T->Left);
    else if (X > T->Element)
        return Find(X, T->Right);

    //不然就是找到了,不进行任何操作
    // printf("%d ", T->Element);
    return T;
}

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

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

    return T;
}

AvlTree Insert(ElementType X, AvlTree T)
{
    /*先插入再回来(从下往上)判断是否平衡*/
    
    if (T == NULL)
    {
        /*Create and return a one-node tree*/
        T = (Position)malloc(sizeof(struct AvlNode));
        if (T == NULL)
        {
            printf("Out of space!!!");
            exit(0);
        }
        else
        {
            T->Element = X;
            T->Height = 0;
            T->Left = T->Right = NULL;
        }
    }
    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 = SingleRotationWithLeft(T);
            else
                T = doubleRotationWithLeft(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 = SingleRotationWithRight(T);
            else
                T = doubleRotationWithRight(T);
        }

        /*Else x is in the tree already;we'll do nothing*/

        T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
        return T;
    }
}


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

/*This function can be called only if K2 has a left child*/
/*Perform a rotate between a node (K2) and its left chid*/
/*update heights, then return new root*/
static Position SingleRotationWithLeft(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; /*New root*/
}

static Position doubleRotationWithLeft(Position K3)
{ /*先左旋在右旋*/
    /*Rotate between K1 and K2*/
    K3->Left = SingleRotationWithRight(K3->Left);

    /*Rotate between K3 and K2*/
    return SingleRotationWithLeft(K3);
}

static Position SingleRotationWithRight(Position K2)
{
    Position K1;

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

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

    return K1;
}
static Position doubleRotationWithRight(Position K3)
{
    //右-左型先右旋在左旋
    K3->Right = SingleRotationWithLeft(K3->Right);

    return SingleRotationWithRight(K3);
}

AvlTree Delete(ElementType X, AvlTree T)
{
    Position TmpCell;

    if (T == NULL)
    {
        printf("Element not found\n");
    }
    else if (X < T->Element)
    {
        T->Left = Delete(X, T->Left);
        /*返回后檢查是否不怕很*/
        if (Height(T->Left) - Height(T->Right) == 2)
        {
            if (X < T->Left->Element)
                T = SingleRotationWithLeft(T);
            else
                T = doubleRotationWithLeft(T);
        }
    }
    else if (X > T->Element)
    {
        T->Right = Delete(X, T->Right);
        if (Height(T->Right) - Height(T->Left) == 2)
        {
            if (X > T->Right->Element)
                T = SingleRotationWithRight(T);
            else
                T = doubleRotationWithRight(T);
        }
    }
    else if (T->Left && T->Right)
    {
        TmpCell = FindMin(T->Right);
        T->Element = TmpCell->Element;
        T->Right = Delete(T->Element, T->Right);
    }
    else
    { /*One or zero children*/
        TmpCell = T;
        if (T->Left == NULL)
            T = T->Right;
        else if (T->Right == NULL)
            T = T->Left;
        free(TmpCell);
    }

    //判斷是否平衡

    T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
    return T;
}

二叉平衡树

#include <stdio.h>
#include <stdlib.h>
#include "AvlT.c"

int main()
{
    AvlTree T = NULL;
    Position P;

    T = Insert(2, T);
    T = Insert(3, T);
    T = Insert(4, T);
    T = Insert(5, T);
    T = Insert(6, T);
    T = Insert(7, T);
    T = Insert(8, T);
    T = Insert(9, T);
    T = Insert(10, T);
    T = Insert(11, T);
    T = Insert(12, T);
    T = Insert(13, T);
    T = Insert(14, T);
    T = Insert(15, T);
    T = Insert(16, T);
    T = Insert(17, T);
    T = Insert(18, T);
    T = Insert(20, T);
    T = Delete(18, T);
    P = Find(18, T);
    printf("%d", T->Right->Element);
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值