zoukankan      html  css  js  c++  java
  • AVL树模板

      1 ///AVL树模板
      2 typedef struct Node     ///树的节点
      3 {
      4     int val,data;
      5     int h;               ///以当前结点为根结点的数的高度
      6     int bf;             ///平衡因子(左子树高度与右子树高度之差)
      7     Node *left,*right;
      8 }Node;
      9 
     10 class AvlTree          ///alv树,树中太多函数,用类来实现容易一些
     11 {
     12 private:
     13     Node *root;        ///树的根节点
     14 public:
     15     void Init()        ///初始化树
     16     {
     17         root=NULL;
     18     }
     19     int Height(Node *T) ///取一个节点的高度
     20     {
     21         if (T==NULL) return 0;
     22         return T->h;
     23     }
     24     int Bf(Node *T)    ///计算一个节点的平衡因子
     25     {
     26         if (T->left==T->right) return 0;
     27         if (T->left==NULL) return -(T->right->h);  ///这里一定取负数(左子树高度与右子树高度之差)
     28         if (T->right==NULL) return T->left->h;
     29         return (T->left->h)-(T->right->h);
     30     }
     31     ///四种旋转,不知为什么,自己多画一下就知道了。
     32     Node *LL_rotate(Node *T)  ///单向右旋平衡处理LL:由于在*T的左子树根结点的左子树上插入结点
     33     {
     34         Node *B=T->left;
     35         T->left=B->right;
     36         B->right=T;
     37         T->h=max(Height(T->left),Height(T->right))+1;
     38         B->h=max(Height(B->left),Height(T->right))+1;
     39         T->bf=Bf(T);
     40         B->bf=Bf(B);
     41         return B;
     42     }
     43     Node *RR_rotate(Node *T) ///单向左旋平衡处理RR:由于在*T的右子树根结点的右子树上插入结点
     44     {
     45         Node *B=T->right;
     46         T->right=B->left;
     47         B->left=T;
     48         T->h=max(Height(T->left),Height(T->right))+1;
     49         B->h=max(Height(B->left),Height(T->right))+1;
     50         T->bf=Bf(T);
     51         B->bf=Bf(B);
     52         return B;
     53     }
     54     Node *LR_rotate(Node *T)   ///双向旋转平衡处理LR:由于在*T的左子树根结点的右子树上插入结点
     55     {
     56         T->left=RR_rotate(T->left);
     57         T=LL_rotate(T);
     58         return T;
     59     }
     60     Node *RL_rotate(Node *T) ///双向旋转平衡处理RL:由于在*T的右子树根结点的左子树上插入结点
     61     {
     62         T->right=LL_rotate(T->right);
     63         T=RR_rotate(T);
     64         return T;
     65     }
     66     void Insert(int v,int e) ///root是private,所以不能从主函数传入
     67     {
     68         Insert(root,v,e);
     69     }
     70     void Insert(Node *&T,int v,int e) ///插入新节点
     71     {
     72         if (T==NULL)
     73         {
     74             T=(Node *)malloc(sizeof(Node));
     75             T->h=1;
     76             T->bf=0;
     77             T->val=v;
     78             T->data=e;
     79             T->left=T->right=NULL;
     80             return ;
     81         }
     82         if (e<T->data) Insert(T->left,v,e);
     83         else Insert(T->right,v,e);
     84         T->h=max(Height(T->left),Height(T->right))+1;  ///计算节点高度
     85         T->bf=Bf(T);                                   ///计算平衡因子
     86         if (T->bf>1||T->bf<-1)                         ///调整平衡,四种调整反法
     87         {
     88             if (T->bf>1&&T->left->bf>0) T=LL_rotate(T);  ///如果T->bf > 1 则肯定有左儿子
     89             if (T->bf<-1&&T->right->bf<0) T=RR_rotate(T); ///如果T->bf < -1 则肯定有右儿子
     90             if (T->bf>1&&T->left->bf<0) T=LR_rotate(T);
     91             if (T->bf<-1&&T->right>0) T=RL_rotate(T);
     92         }
     93     }
     94     void Find(int flag)   ///flag=1为找最大值,否则找最小值
     95     {
     96         if (root==NULL)
     97         {
     98             printf("0
    ");
     99             return ;
    100         }
    101         Node *temp=root;
    102         if (flag)     ///最大值一定最右边
    103         {
    104             while (temp->right)
    105             temp=temp->right;
    106         }
    107         else
    108         {
    109             while (temp->left)
    110             temp=temp->left;
    111         }
    112         printf("%d
    ",temp->val);
    113         Delete(root,temp->data);   ///删除相应节点
    114     }
    115     void Delete(Node *&T,int e)    
    116     {
    117         if (T==NULL) return ;
    118         if (e<T->data) Delete(T->left,e);
    119         else if (e>T->data) Delete(T->right,e);
    120         else    ///找到删除的节点
    121         {
    122             if (T->left&&T->right)  ///删除的节点左右都还有节点
    123             {
    124                 Node *temp=T->left; ///把左子树的最大值当做当前节点
    125                 while (temp->right) temp=temp->right; ///找最大值
    126                 T->val=temp->val;
    127                 T->data=temp->data;
    128                 Delete(T->left,temp->data);  ///左子树最大值已近改为当前根节点,应该删除原来位置
    129             }
    130             else
    131             {
    132                 Node *temp=T;
    133                 if (T->left) T=T->left;     ///删除节点只存在左子树
    134                 else if (T->right) T=T->right; ///删除节点只有右子树
    135                 else             ///删除节点没有孩子
    136                 {
    137                     free(T);
    138                     T=NULL;
    139                 }
    140                 if (T) free(temp);
    141                 return ;
    142             }
    143         }
    144         T->h=max(Height(T->left),Height(T->right))+1;
    145         T->bf=Bf(T);
    146         if (T->bf>1||T->bf<-1)   ///删除后一定要调整
    147         {
    148             if (T->bf>1&&T->left->bf>0) T=LL_rotate(T);
    149             if (T->bf<-1&&T->right->bf<0) T=RR_rotate(T);
    150             if (T->bf>1&&T->left->bf<0) T=LR_rotate(T);
    151             if (T->bf<-1&&T->right>0) T=RL_rotate(T);
    152         }
    153     }
    154     void Free()  ///由于内存是malloc出来的,最后一定要释放
    155     {
    156         FreeNode(root);
    157     }
    158     void FreeNode(Node *T)
    159     {
    160         if (T==NULL) return ;
    161         if (T->right) FreeNode(T->right);
    162         if (T->left) FreeNode(T->left);
    163         free(T);
    164     }
    165 };
  • 相关阅读:
    NOIP 2012 文化之旅
    史上最全的各种C++ STL容器全解析
    详解C++ STL map 容器
    详解C++ STL priority_queue 容器
    浅谈C++ STL stack 容器
    浅谈C++ STL queue 容器
    浅谈C++ STL vector 容器
    CF1185F Two Pizzas
    浅谈C++ STL deque 容器
    详解C++ STL multiset 容器
  • 原文地址:https://www.cnblogs.com/pblr/p/5750564.html
Copyright © 2011-2022 走看看