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\n");
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\n",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 }

 

posted on 2016-08-08 18:32  pb2016  阅读(680)  评论(0编辑  收藏  举报