zoukankan      html  css  js  c++  java
  • poj 3841 Double Queue (AVL树入门)

      1 /******************************************************************
      2 题目:     Double Queue(poj 3481)
      3 链接:     http://poj.org/problem?id=3481
      4 算法:     avl树(入门)
      5 *******************************************************************/
      6 #include<cstdio>
      7 #include<cstring>
      8 #include<cstdlib>
      9 #include<iostream>
     10 #include<algorithm>
     11 using namespace std;
     12 
     13 typedef struct Node     ///树的节点
     14 {
     15     int val,data;
     16     int h;               ///以当前结点为根结点的数的高度
     17     int bf;             ///平衡因子(左子树高度与右子树高度之差)
     18     Node *left,*right;
     19 }Node;
     20 
     21 class AvlTree          ///alv树,树中太多函数,用类来实现容易一些
     22 {
     23 private:
     24     Node *root;        ///树的根节点
     25 public:
     26     void Init()        ///初始化树
     27     {
     28         root=NULL;
     29     }
     30     int Height(Node *T) ///取一个节点的高度
     31     {
     32         if (T==NULL) return 0;
     33         return T->h;
     34     }
     35     int Bf(Node *T)    ///计算一个节点的平衡因子
     36     {
     37         if (T->left==T->right) return 0;
     38         if (T->left==NULL) return -(T->right->h);  ///这里一定取负数(左子树高度与右子树高度之差)
     39         if (T->right==NULL) return T->left->h;
     40         return (T->left->h)-(T->right->h);
     41     }
     42     ///四种旋转,不知为什么,自己多画一下就知道了。
     43     Node *LL_rotate(Node *T)  ///单向右旋平衡处理LL:由于在*T的左子树根结点的左子树上插入结点
     44     {
     45         Node *B=T->left;
     46         T->left=B->right;
     47         B->right=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 *RR_rotate(Node *T) ///单向左旋平衡处理RR:由于在*T的右子树根结点的右子树上插入结点
     55     {
     56         Node *B=T->right;
     57         T->right=B->left;
     58         B->left=T;
     59         T->h=max(Height(T->left),Height(T->right))+1;
     60         B->h=max(Height(B->left),Height(T->right))+1;
     61         T->bf=Bf(T);
     62         B->bf=Bf(B);
     63         return B;
     64     }
     65     Node *LR_rotate(Node *T)   ///双向旋转平衡处理LR:由于在*T的左子树根结点的右子树上插入结点
     66     {
     67         T->left=RR_rotate(T->left);
     68         T=LL_rotate(T);
     69         return T;
     70     }
     71     Node *RL_rotate(Node *T) ///双向旋转平衡处理RL:由于在*T的右子树根结点的左子树上插入结点
     72     {
     73         T->right=LL_rotate(T->right);
     74         T=RR_rotate(T);
     75         return T;
     76     }
     77     void Insert(int v,int e) ///root是private,所以不能从主函数传入
     78     {
     79         Insert(root,v,e);
     80     }
     81     void Insert(Node *&T,int v,int e) ///插入新节点
     82     {
     83         if (T==NULL)
     84         {
     85             T=(Node *)malloc(sizeof(Node));
     86             T->h=1;
     87             T->bf=0;
     88             T->val=v;
     89             T->data=e;
     90             T->left=T->right=NULL;
     91             return ;
     92         }
     93         if (e<T->data) Insert(T->left,v,e);
     94         else Insert(T->right,v,e);
     95         T->h=max(Height(T->left),Height(T->right))+1;  ///计算节点高度
     96         T->bf=Bf(T);                                   ///计算平衡因子
     97         if (T->bf>1||T->bf<-1)                         ///调整平衡,四种调整反法
     98         {
     99             if (T->bf>1&&T->left->bf>0) T=LL_rotate(T);  ///如果T->bf > 1 则肯定有左儿子
    100             if (T->bf<-1&&T->right->bf<0) T=RR_rotate(T); ///如果T->bf < -1 则肯定有右儿子
    101             if (T->bf>1&&T->left->bf<0) T=LR_rotate(T);
    102             if (T->bf<-1&&T->right>0) T=RL_rotate(T);
    103         }
    104     }
    105     void Find(int flag)   ///flag=1为找最大值,否则找最小值
    106     {
    107         if (root==NULL)
    108         {
    109             printf("0
    ");
    110             return ;
    111         }
    112         Node *temp=root;
    113         if (flag)     ///最大值一定最右边
    114         {
    115             while (temp->right)
    116             temp=temp->right;
    117         }
    118         else
    119         {
    120             while (temp->left)
    121             temp=temp->left;
    122         }
    123         printf("%d
    ",temp->val);
    124         Delete(root,temp->data);   ///删除相应节点
    125     }
    126     void Delete(Node *&T,int e)    
    127     {
    128         if (T==NULL) return ;
    129         if (e<T->data) Delete(T->left,e);
    130         else if (e>T->data) Delete(T->right,e);
    131         else    ///找到删除的节点
    132         {
    133             if (T->left&&T->right)  ///删除的节点左右都还有节点
    134             {
    135                 Node *temp=T->left; ///把左子树的最大值当做当前节点
    136                 while (temp->right) temp=temp->right; ///找最大值
    137                 T->val=temp->val;
    138                 T->data=temp->data;
    139                 Delete(T->left,temp->data);  ///左子树最大值已近改为当前根节点,应该删除原来位置
    140             }
    141             else
    142             {
    143                 Node *temp=T;
    144                 if (T->left) T=T->left;     ///删除节点只存在左子树
    145                 else if (T->right) T=T->right; ///删除节点只有右子树
    146                 else             ///删除节点没有孩子
    147                 {
    148                     free(T);
    149                     T=NULL;
    150                 }
    151                 if (T) free(temp);
    152                 return ;
    153             }
    154         }
    155         T->h=max(Height(T->left),Height(T->right))+1;
    156         T->bf=Bf(T);
    157         if (T->bf>1||T->bf<-1)   ///删除后一定要调整
    158         {
    159             if (T->bf>1&&T->left->bf>0) T=LL_rotate(T);
    160             if (T->bf<-1&&T->right->bf<0) T=RR_rotate(T);
    161             if (T->bf>1&&T->left->bf<0) T=LR_rotate(T);
    162             if (T->bf<-1&&T->right>0) T=RL_rotate(T);
    163         }
    164     }
    165     void Free()  ///由于内存是malloc出来的,最后一定要释放
    166     {
    167         FreeNode(root);
    168     }
    169     void FreeNode(Node *T)
    170     {
    171         if (T==NULL) return ;
    172         if (T->right) FreeNode(T->right);
    173         if (T->left) FreeNode(T->left);
    174         free(T);
    175     }
    176 };
    177 AvlTree T;
    178 
    179 int main()
    180 {
    181    T.Init();
    182    int op;
    183    while (~scanf("%d",&op)&&op)
    184    {
    185        if (op==1)
    186        {
    187            int v,e;
    188            scanf("%d%d",&v,&e);
    189            T.Insert(v,e);
    190        }
    191        if (op==2)
    192        {
    193            T.Find(1);
    194        }
    195        if (op==3)
    196        {
    197            T.Find(0);
    198        }
    199    }
    200    T.Free();
    201    return 0;
    202 }
  • 相关阅读:
    开发笔记--git代码回退,撤回到上一个版本
    开发笔记--Navicat导出postgresql表结构数据成excel文件
    使用Aspose.Words组件给word加水印
    JSON JavaScriptSerializer 字符串的长度超过了为 maxJsonLength 属性设置的值。
    http content-type详解
    Linux CPU使用率超过100%的原因
    Qt查找依赖库的简单方法及如何简便地在pro中添加依赖库
    OSI七层网络模型分别是哪七层?各运行那些协议?
    配置文件管理
    Java中日期转json时日期格式转换
  • 原文地址:https://www.cnblogs.com/pblr/p/5750554.html
Copyright © 2011-2022 走看看