AvlTree

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

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


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

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


/* Function to compute height of an AVL node */
static int Height(Position P) {
    if (P == NULL)
        return -1;
    else
        return P->Height;
}

void DispTree(AvlTree T) {
    if (T) {
        printf("%d\t", T->Element);
        DispTree(T->Left);
        DispTree(T->Right);
    }
}

int Max(int x, int y) {
    return x - y ? x : y;
}
/* This function can be called only if K2 has left child */
/* Perform a rotate between a node (K2) and its left child */
/* Update heights, then return new root */
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; /* New root */
}

static Position SingleRotateWithRight(Position &K2) {
    Position K1;
    K1 = K2->Right;
    K2->Right = K1->Left;
    K1->Left = K2;
    K1->Height = Max(K2->Height, Height(K1->Right)) + 1;
    K2->Height = Max(Height(K2->Left), Height(K1->Right)) + 1;
    return K1;
}

/*
 * Routine to perform double rotation
 * This function can be called only if K3 has a left
 * Child and K3's left child has a right child
 * Do the left-right double rotation
 * Update heights, then return new root
 */
static Position DoubleRotateWithLeft(Position &K3) {
    /* Rotate between K1 and K2 */
    K3->Left = SingleRotateWithRight(K3->Left);
    /* Rotate between K3 and K2 */
    return SingleRotateWithLeft(K3);
}

static Position DoubleRotateWithRight(Position &K3) {
    /* Rotate between K1 and K2 */
    K3->Right = SingleRotateWithLeft(K3->Right);
    /* Rotate between K3 and K2 */
    return SingleRotateWithRight(K3);
}

/* Insertion into an AVL tree */
AvlTree Insert(ElementType X, AvlTree &T) {
    if (T == NULL) {
        /* Create and return a one-node tree */
        T = (AvlNode *) malloc(sizeof(AvlNode));
        if (T == NULL)
            printf("Out of space");
        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 = SingleRotateWithLeft(T);
            else
                T = DoubleRotateWithLeft(T);
    } else if (X > T->Element) {
        T->Right = Insert(X, T->Right);
        if (Height(T->Right) - Height(T->Right) == 2)
            if (X > T->Right->Element)
                T = SingleRotateWithRight(T);
            else
                T = DoubleRotateWithRight(T);

    }
    /* Else X is in the tree already; we'll do nothing */
    T->Height = Max(Height(T->Left), Height(T->Right)) + 1;
    return T;
}

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

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

AvlTree SearchPreviousNode(AvlTree T1, AvlTree T2) {
    if (T2) {
        if (T2->Left == T1 || T2->Right == T1)
            return T2;
        SearchPreviousNode(T1, T2->Left);
        SearchPreviousNode(T1, T2->Right);
    }
    return NULL;
}

AvlTree Delete(ElementType X, AvlTree &T) {
    AvlNode *TmpCell = NULL;
    if (T == NULL) {
        printf("删除节点不存在");
        return NULL;
    } else if (X > T->Element) {
        T->Right = Delete(X, T->Right); /* 在右边进行了删除 */
        if (Height(T->Left) - Height(T->Right) > 1) { /* 原来是平衡二叉树,现在右边的高度可能减少了,判断是否平衡 */
            TmpCell = T->Left; /* 左子树高一点,接着查看左子树的左子树 */
            if (Height(TmpCell->Left) >= Height(TmpCell->Right)) /* 查看造成不平衡的是否在左边 即左子树的左子树高一点*/
                T = SingleRotateWithRight(T);
            else /* 左子树的右子树高一点 LR */
                T = DoubleRotateWithRight(T);
        }
        T->Height = Height(T);
    } else if (X < T->Element) {
        T->Left = Delete(X, T->Left);
        if (Height(T->Right) - Height(T->Left) > 1) { /* 删除后如果失衡 */
            TmpCell = T->Right; /* 右子树比左子树高 */
            if (Height(TmpCell->Right) >= Height(TmpCell->Left)) /* 做RR */
                T = SingleRotateWithRight(T);
            else
                T = DoubleRotateWithLeft(T); /* 做RL */
        }
        T->Height = Height(T); /* 更新高度 */
    } else if (X == T->Element) {
        if (T->Right && T->Left) {
            TmpCell = FindMin(T->Right); /* 左右孩子都有时,找到右边最小的,补到T的位置,然后将在T右边最小的删除 */
            T->Element = TmpCell->Element;
            T->Right = Delete(T->Element, T->Right);
        } else {/* 只有一个孩子 */
            TmpCell = T;
            if (T->Left == NULL)
                T = T->Left;
            else if (T->Right == NULL)
                T = T->Right;
            free(TmpCell);
        }
    }
    return T;

}
posted @ 2022-04-10 16:45  里列昂遗失的记事本  阅读(30)  评论(0)    收藏  举报