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\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 }
时间: 2024-11-05 02:38:11

poj 3841 Double Queue (AVL树入门)的相关文章

AVL树(模板题)—— POJ 3481 Double Queue

对应POJ题目:点击打开链接 Double Queue Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11741   Accepted: 5335 Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing env

POJ 3481 Double Queue(Treap模板题)

Double Queue Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15786   Accepted: 6998 Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing environment provid

跳跃表基础——POJ 3481 Double Queue

对应POJ 题目:点击打开链接 Double Queue Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11768   Accepted: 5349 Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing en

POJ - 3481 - Double Queue (STL)

Double Queue Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11133   Accepted: 5056 Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing environment provid

POJ 3481 Double Queue(STL)

题意  模拟银行的排队系统  有三种操作  1-加入优先级为p 编号为k的人到队列  2-服务当前优先级最大的   3-服务当前优先级最小的  0-退出系统 能够用stl中的map   由于map本身就依据key的值排了序   相应2.3  我们仅仅须要输出最大或最小即可了并从map中删除该键值 #include<cstdio> #include<map> using namespace std; map<int, int> a; int main() { map<

POJ 3481 Double Queue 堆修改标记

Enemy Double Queue! 题目大意:维护一种数据结构,支持以下操作: 1.插入一个值 2.查询最大值并删除 3.查询最小值并删除 元素的值<=1000W 这数据结构一看就是堆...不过堆结构不能同时维护最大值和最小值,于是我们开两个堆,一个大根堆,一个小根堆 其中一堆删除时,另一堆也要删除相应元素 于是删除的话有两种方法 1.映射 1000W开数组映射妥妥MLE 于是我们在两个堆之间互相映射 不太好写 pair里开自己的指针会报错,于是只能开了void* 不过速度还是很可观的 #i

AVL树入门(转载)

原文链接:http://lib.csdn.net/article/datastructure/9204           作者:u011469062 前言:本文不适合 给一组数据15分钟就能实现AVL的插入和删除操作的大牛(也请大牛不要打击小菜) 本文适合,对avl还不了解,还没有亲自实现avl的插入和删除操作的同学 ps,你在嘲笑楼主的题目时,你已证明了自己正在嘲笑自己的智商.我们要善于征服陌生的事物.你如果有半个小时时间就心无杂念的开始吧,建议那些读10分钟文章就心燥还是关闭浏览器吧. 文

POJ 3481 Double Queue(set实现)

Double Queue The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest, equipped with a modern computing environment provided by IBM Romania, and using modern information technologies. As usual, each client of the bank

poj 1442 Black Box (treap树入门题)

1 /**************************************************** 2 题目: Black Box(poj 1442) 3 链接: http://poj.org/problem?id=1442 4 题意: 给n个数,m个询问,对第i数个询问前Xi个数中第 5 i小的是那个数. 6 算法: treap树 7 *****************************************************/ 8 #include<iostream