zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Flink 双流合并之connect Demo2
    Flink 双流合并之connect Demo1
    Flink 双流合并Join
    Flink状态保存CheckPoint
    Flink状态之OperatorState
    Flink状态之AggregateState
    Flink状态之ReduceState
    Flink状态之MapState
    Flink状态之KeyedListState
    大数据框架环境安装与配置01--服务器基本设置
  • 原文地址:https://www.cnblogs.com/hrcadx/p/5970935.html
Copyright © 2011-2022 走看看