AVL树插入删除

写了好久,感觉插入和删除麻烦些,插入也就4种情况,但只要写两个函数,左左和右右的,左右的情况是以根节点的左子树为头进行一次右右旋转,使它变成左左的情况,再左左旋转下就行了,右左的也一样;

另外就是删除,先是判断要删除的节点右儿子是否为空,是空,直接删,否则找到它右儿子的最左边的儿子来替代它,然后就是高度的更新,重新的旋转。。。

哎,真实花了我好长时间,不过终于写完了。大致感觉没啥问题了吧,有的话以后再改吧。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stdlib.h>
#include <cmath>

using namespace std;


typedef struct AvlNode              // AVL树的节点
{
    int data;
    struct AvlNode *left;           // 左孩子
    struct AvlNode *right;          // 右孩子
    int Height;
}*Position,*AvlTree;

AvlTree MakeEmpty(AvlTree T);
Position Find(int x,AvlTree T);
Position Find_right(AvlTree T);
Position FindMax(AvlTree T);

int Search(AvlTree T);
AvlTree  Insert(int x,AvlTree T);
AvlTree  Delete(int  x,AvlTree T);

AvlTree left_left(AvlTree k1);
AvlTree right_right(AvlTree k1);
AvlTree left_right(AvlTree k1);
AvlTree right_left(AvlTree k1);
AvlTree Printf_tree(AvlTree T);
AvlTree balance(AvlTree T);

int main()
{
    AvlTree T =NULL;
    getchar();
   T=Insert(2,T);
   T= Insert(7,T);
     //Printf_tree(T);
    T= Insert(5,T);
    //Printf_tree(T);
    T=Insert(11,T);
    T=Insert(9,T);
    T=Insert(10,T);
    T=Insert(100,T);
    T=Insert(14,T);
    T=Insert(20,T);
   Printf_tree(T);
  T = Delete(5,T);
   printf("
");
   Printf_tree(T);
    printf("
");
    T = Delete(2,T);
     Printf_tree(T);
    getchar();
    return 0;
}
AvlTree MakeEmpty(AvlTree T)
{
    if(T!=NULL)
    {
        MakeEmpty(T->left);
        MakeEmpty(T->right);
        free(T);
    }
    return NULL;
}

int height(AvlTree T)
{
    if(T==NULL)return -1;
    else return T->Height;
}

//向树中插入数据
AvlTree Insert(int x,AvlTree T)
{
    if(T==NULL)
    {
        T = (AvlTree)malloc(sizeof(struct AvlNode));
        T->data = x;
        T->Height = 0;
        T->left = NULL;
        T->right = NULL;
    }
    //如果插入元素小于当前元素
    else if(x<T->data)
    {
        T->left = Insert(x,T->left);
        if(height(T->left)-height(T->right)==2)
        {
            if(x<T->left->data)
                T = left_left(T);
            else
                T = left_right(T);
        }

    }
    else if(x>T->data)
    {
        T->right = Insert(x,T->right);
        if(height(T->right)-height(T->left)==2)
        {
            if(x<T->right->data)
                T = right_left(T);
            else
                T = right_right(T);
        }
    }
    T->Height = max(height(T->left),height(T->right))+1;
    return T;
}

//左左旋转
AvlTree left_left(AvlTree k1)
{
    //if(height(k1->left)-height(k1->right)<2)return k1;
    AvlTree k2 = k1->left;
    k1->left = k2->right;
    k2->right = k1;
   k1->Height = max(height(k1->left),height(k1->right))+1;
    k2->Height = max(height(k2->left),height(k2->right))+1;
    return k2;
}

//右右旋转

AvlTree right_right(AvlTree k1)
{
    //if(height(k1->right)-height(k1->left)<2)return k1;
    AvlTree k2 = k1->right;
    k1->right = k2->left;
    k2->left = k1;
    k1->Height = max(height(k1->left),height(k1->right))+1;
    k2->Height = max(height(k2->left),height(k2->right))+1;
    return k2;
}

//左右旋转

AvlTree left_right(AvlTree k1)
{
    k1->left = right_right(k1->left);
    return left_left(k1);
}

//右左旋转

AvlTree right_left(AvlTree k1)
{
    k1->right = left_left(k1->right);
    return right_right(k1);
}

AvlTree Printf_tree(AvlTree T)
{
    if(T==NULL)return NULL;
    else
    {
        printf("父亲节点是:%d ",T->data);
        printf("左儿子是: ");
        if(T->left==NULL)printf("NULL");
       else printf("%d",T->left->data);
       printf("右儿子是:");
       if(T->right==NULL)printf("NULL");
       else printf("%d",T->right->data);
       printf(" 高度是:%d
",height(T));
    }
    Printf_tree(T->left);
    Printf_tree(T->right);
}

AvlTree Delete(int x,AvlTree T)
{
    if(T==NULL)return NULL;
    else
    {
        if(T->data==x)
        {
            if(T->right==NULL)
            {
                AvlTree tem = T;
                T = T->left;
                free(tem);
            }
            else
            {
                AvlTree tem = T->right;
                while(tem->left!=NULL)
                {
                    tem = tem->left;
                }
                T->data = tem->data;
                //free(tem);
                //tem=NULL;
                T->right = Delete(T->data,T->right);
                T->Height = max(height(T->left),height(T->right))+1;
            }
            return T;
        }
        else if(x>T->data)
        {
            T->right = Delete(x,T->right);
        }
        else if(x<T->data)
        {
            T->left = Delete(x,T->left);
        }

        //删除后判断是否平衡,不平衡则需旋转
        T->Height = max(height(T->left),height(T->right))+1;
        if(T->left!=NULL)
        {
            T->left = balance(T->left);
        }
        if(T->right!=NULL)
        {
            T->right = balance(T->right);
        }
        if(T!=NULL)
        {
            T = balance(T);
        }
        return T;
    }
}

AvlTree balance(AvlTree T)
{
    if(height(T->left)-height(T->right)==2)
    {
        if(height(T->left->left)>height(T->left->right))
        {
            T = left_left(T);
        }
        else
        {
            T = left_right(T);
        }
    }
    else if(height(T->right)-height(T->left)==2)
    {
        if(height(T->right)-height(T->left))
        {
            T = right_right(T);
        }
        else
        {
            T = right_left(T);
        }
    }
    else
    {
        return T;
    }
}
View Code

http://poj.org/problem?id=3481

POJ 3481

大意3中操作,1是插入数据,2是输出优先级最大的编号,3是输出优先级最小的编号,一遍过

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stdlib.h>
#include <cmath>

using namespace std;

typedef struct _DATA
{
    int answer;
    int pori;
}DATA;
typedef struct AvlNode              // AVL树的节点
{
    DATA data;
    struct AvlNode *left;           // 左孩子
    struct AvlNode *right;          // 右孩子
    int Height;
}*Position,*AvlTree;

AvlTree MakeEmpty(AvlTree T);
Position Find(int x,AvlTree T);
Position Find_right(AvlTree T);
Position FindMax(AvlTree T);

int Search(AvlTree T);
AvlTree  Insert(DATA x,AvlTree T);
AvlTree  Delete(DATA x,AvlTree T);

AvlTree left_left(AvlTree k1);
AvlTree right_right(AvlTree k1);
AvlTree left_right(AvlTree k1);
AvlTree right_left(AvlTree k1);
AvlTree Printf_tree(AvlTree T);
AvlTree balance(AvlTree T);
DATA Find_max(AvlTree T);
DATA Find_min(AvlTree T);

int main()
{
    int n;
    AvlTree T = NULL;
    while(scanf("%d",&n)!=EOF&&n)
    {
        if(n==1)
        {
            DATA a;
            scanf("%d%d",&a.answer,&a.pori);
            T = Insert(a,T);
        }
        if(n==2)
        {
            if(T==NULL)printf("0
");
            else
            {
                DATA tem = Find_max(T);
                T = Delete(tem,T);
                printf("%d
",tem.answer);
            }
        }
        if(n==3)
        {
            if(T==NULL)printf("0
");
            else
            {
                DATA tem = Find_min(T);
                T = Delete(tem,T);
                printf("%d
",tem.answer);
            }

        }
    }
    return 0;
}
AvlTree MakeEmpty(AvlTree T)
{
    if(T!=NULL)
    {
        MakeEmpty(T->left);
        MakeEmpty(T->right);
        free(T);
    }
    return NULL;
}

int height(AvlTree T)
{
    if(T==NULL)return -1;
    else return T->Height;
}

//向树中插入数据
AvlTree Insert(DATA x,AvlTree T)
{
    if(T==NULL)
    {
        T = (AvlTree)malloc(sizeof(struct AvlNode));
        T->data = x;
        T->Height = 0;
        T->left = NULL;
        T->right = NULL;
    }
    //如果插入元素小于当前元素
    else if(x.pori<T->data.pori)
    {
        T->left = Insert(x,T->left);
        if(height(T->left)-height(T->right)==2)
        {
            if(x.pori<T->left->data.pori)
                T = left_left(T);
            else
                T = left_right(T);
        }

    }
    else if(x.pori>T->data.pori)
    {
        T->right = Insert(x,T->right);
        if(height(T->right)-height(T->left)==2)
        {
            if(x.pori<T->right->data.pori)
                T = right_left(T);
            else
                T = right_right(T);
        }
    }
    T->Height = max(height(T->left),height(T->right))+1;
    return T;
}

//左左旋转
AvlTree left_left(AvlTree k1)
{
    //if(height(k1->left)-height(k1->right)<2)return k1;
    AvlTree k2 = k1->left;
    k1->left = k2->right;
    k2->right = k1;
   k1->Height = max(height(k1->left),height(k1->right))+1;
    k2->Height = max(height(k2->left),height(k2->right))+1;
    return k2;
}

//右右旋转

AvlTree right_right(AvlTree k1)
{
    //if(height(k1->right)-height(k1->left)<2)return k1;
    AvlTree k2 = k1->right;
    k1->right = k2->left;
    k2->left = k1;
    k1->Height = max(height(k1->left),height(k1->right))+1;
    k2->Height = max(height(k2->left),height(k2->right))+1;
    return k2;
}

//左右旋转

AvlTree left_right(AvlTree k1)
{
    k1->left = right_right(k1->left);
    return left_left(k1);
}

//右左旋转

AvlTree right_left(AvlTree k1)
{
    k1->right = left_left(k1->right);
    return right_right(k1);
}

/*AvlTree Printf_tree(AvlTree T)
{
    if(T==NULL)return NULL;
    else
    {
        printf("父亲节点是:%d ",T->data);
        printf("左儿子是: ");
        if(T->left==NULL)printf("NULL");
       else printf("%d",T->left->data);
       printf("右儿子是:");
       if(T->right==NULL)printf("NULL");
       else printf("%d",T->right->data);
       printf(" 高度是:%d
",height(T));
    }
    Printf_tree(T->left);
    Printf_tree(T->right);
}*/

AvlTree Delete(DATA x,AvlTree T)
{
    if(T==NULL)return NULL;
    else
    {
        if(T->data.pori==x.pori)
        {
            if(T->right==NULL)
            {
                AvlTree tem = T;
                T = T->left;
                free(tem);
            }
            else
            {
                AvlTree tem = T->right;
                while(tem->left!=NULL)
                {
                    tem = tem->left;
                }
                T->data = tem->data;
                //free(tem);
                //tem=NULL;
                T->right = Delete(T->data,T->right);
                T->Height = max(height(T->left),height(T->right))+1;
            }
            return T;
        }
        else if(x.pori>T->data.pori)
        {
            T->right = Delete(x,T->right);
        }
        else if(x.pori<T->data.pori)
        {
            T->left = Delete(x,T->left);
        }

        //删除后判断是否平衡,不平衡则需旋转
        T->Height = max(height(T->left),height(T->right))+1;
        if(T->left!=NULL)
        {
            T->left = balance(T->left);
        }
        if(T->right!=NULL)
        {
            T->right = balance(T->right);
        }
        if(T!=NULL)
        {
            T = balance(T);
        }
        return T;
    }
}

AvlTree balance(AvlTree T)
{
    if(height(T->left)-height(T->right)==2)
    {
        if(height(T->left->left)>height(T->left->right))
        {
            T = left_left(T);
        }
        else
        {
            T = left_right(T);
        }
    }
    else if(height(T->right)-height(T->left)==2)
    {
        if(height(T->right)-height(T->left))
        {
            T = right_right(T);
        }
        else
        {
            T = right_left(T);
        }
    }
    else
    {
        return T;
    }
}

DATA Find_max(AvlTree T)
{
    AvlTree tem = T;
    while(tem->right!=NULL)
    {
        tem = tem->right;
    }
    return tem->data;
}

DATA Find_min(AvlTree T)
{
    AvlTree tem = T;
    while(tem->left!=NULL)
    {
        tem = tem->left;
    }
    return tem->data;
}
View Code
原文地址:https://www.cnblogs.com/hrcadx/p/5970935.html