SDUTOJ 3374 数据结构实验之查找二:平衡二叉树

题目链接:http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Index/problemdetail/pid/3374.html

题目大意

  略。

分析

  要手写 AVL 树,而红黑树,SB 树,跳表不可以。

代码如下

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3
  4 #define INIT() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  5 #define Rep(i,n) for (int i = 0; i < (int)(n); ++i)
  6 #define For(i,s,t) for (int i = (int)(s); i <= (int)(t); ++i)
  7 #define rFor(i,t,s) for (int i = (int)(t); i >= (int)(s); --i)
  8 #define ForLL(i, s, t) for (LL i = LL(s); i <= LL(t); ++i)
  9 #define rForLL(i, t, s) for (LL i = LL(t); i >= LL(s); --i)
 10 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
 11 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
 12
 13 #define pr(x) cout << #x << " = " << x << "  "
 14 #define prln(x) cout << #x << " = " << x << endl
 15
 16 #define LOWBIT(x) ((x)&(-x))
 17
 18 #define ALL(x) x.begin(),x.end()
 19 #define INS(x) inserter(x,x.begin())
 20 #define UNIQUE(x) x.erase(unique(x.begin(), x.end()), x.end())
 21 #define REMOVE(x, c) x.erase(remove(x.begin(), x.end(), c), x.end()); // 删去 x 中所有 c
 22 #define TOLOWER(x) transform(x.begin(), x.end(), x.begin(),::tolower);
 23 #define TOUPPER(x) transform(x.begin(), x.end(), x.begin(),::toupper);
 24
 25 #define ms0(a) memset(a,0,sizeof(a))
 26 #define msI(a) memset(a,0x3f,sizeof(a))
 27 #define msM(a) memset(a,-1,sizeof(a))
 28
 29 #define MP make_pair
 30 #define PB push_back
 31 #define ft first
 32 #define sd second
 33
 34 template<typename T1, typename T2>
 35 istream &operator>>(istream &in, pair<T1, T2> &p) {
 36     in >> p.first >> p.second;
 37     return in;
 38 }
 39
 40 template<typename T>
 41 istream &operator>>(istream &in, vector<T> &v) {
 42     for (auto &x: v)
 43         in >> x;
 44     return in;
 45 }
 46
 47 template<typename T>
 48 ostream &operator<<(ostream &out, vector<T> &v) {
 49     Rep(i, v.size()) out << v[i] << " \n"[i == v.size()];
 50     return out;
 51 }
 52
 53 template<typename T1, typename T2>
 54 ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
 55     out << "[" << p.first << ", " << p.second << "]" << "\n";
 56     return out;
 57 }
 58
 59 inline int gc(){
 60     static const int BUF = 1e7;
 61     static char buf[BUF], *bg = buf + BUF, *ed = bg;
 62
 63     if(bg == ed) fread(bg = buf, 1, BUF, stdin);
 64     return *bg++;
 65 }
 66
 67 inline int ri(){
 68     int x = 0, f = 1, c = gc();
 69     for(; c<48||c>57; f = c==‘-‘?-1:f, c=gc());
 70     for(; c>47&&c<58; x = x*10 + c - 48, c=gc());
 71     return x*f;
 72 }
 73
 74 template<class T>
 75 inline string toString(T x) {
 76     ostringstream sout;
 77     sout << x;
 78     return sout.str();
 79 }
 80
 81 inline int toInt(string s) {
 82     int v;
 83     istringstream sin(s);
 84     sin >> v;
 85     return v;
 86 }
 87
 88 //min <= aim <= max
 89 template<typename T>
 90 inline bool BETWEEN(const T aim, const T min, const T max) {
 91     return min <= aim && aim <= max;
 92 }
 93
 94 typedef long long LL;
 95 typedef unsigned long long uLL;
 96 typedef vector< int > VI;
 97 typedef vector< bool > VB;
 98 typedef vector< char > VC;
 99 typedef vector< double > VD;
100 typedef vector< string > VS;
101 typedef vector< LL > VL;
102 typedef vector< VI > VVI;
103 typedef vector< VB > VVB;
104 typedef vector< VS > VVS;
105 typedef vector< VL > VVL;
106 typedef vector< VVI > VVVI;
107 typedef vector< VVL > VVVL;
108 typedef pair< int, int > PII;
109 typedef pair< LL, LL > PLL;
110 typedef pair< int, string > PIS;
111 typedef pair< string, int > PSI;
112 typedef pair< string, string > PSS;
113 typedef pair< double, double > PDD;
114 typedef vector< PII > VPII;
115 typedef vector< PLL > VPLL;
116 typedef vector< VPII > VVPII;
117 typedef vector< VPLL > VVPLL;
118 typedef vector< VS > VVS;
119 typedef map< int, int > MII;
120 typedef unordered_map< int, int > uMII;
121 typedef map< LL, LL > MLL;
122 typedef map< string, int > MSI;
123 typedef map< int, string > MIS;
124 typedef set< int > SI;
125 typedef stack< int > SKI;
126 typedef queue< int > QI;
127 typedef priority_queue< int > PQIMax;
128 typedef priority_queue< int, VI, greater< int > > PQIMin;
129 const double EPS = 1e-8;
130 const LL inf = 0x7fffffff;
131 const LL infLL = 0x7fffffffffffffffLL;
132 const LL mod = 1e9 + 7;
133 const int maxN = 1e2 + 7;
134 const LL ONE = 1;
135 const LL evenBits = 0xaaaaaaaaaaaaaaaa;
136 const LL oddBits = 0x5555555555555555;
137
138 template < typename T >
139 struct AVLTreeNode {
140     T key;
141     int num;
142     int height;
143     AVLTreeNode< T > *lchild, *rchild;
144
145     AVLTreeNode(T value, AVLTreeNode< T > *l, AVLTreeNode< T > *r) : key(value), lchild(l), rchild(r){ num = 1; }
146 };
147
148 template < typename T >
149 class AVLTree {
150 public:
151     AVLTree() { root = nullptr; sz = 0; }           //构造函数
152     ~AVLTree() { destory(); }               //析构函数
153
154     void preOrder() { preOrder(root); }      //前序遍历AVL树
155     void inOrder() { inOrder(root); }        //中序遍历AVL树
156     void postOrder() { postOrder(root); }    //后序遍历AVL树
157
158     void destory() { destory(root); }        //销毁AVL树
159
160     void insert(T key) { insert(root, key); }    //插入指定值的节点
161     void remove(T key) { remove(root, key); }    //移除指定值的节点
162     void remove(AVLTreeNode< T >* pdel) { remove(root, pdel->key); }   //移除指定值的节点
163
164     AVLTreeNode< T >* search_recurse(T key) { search_recurse(root, key); }    //利用递归算法进行指定值的查找
165     AVLTreeNode< T >* search_iterator(T key) { search_iterator(root, key); }    //利用迭代算法进行指定值的查找
166     T minimum();        //返回AVL中的最小值
167     T maximum();        //返回AVL中的最大值
168
169     int height() { return height(root); }        //返回树的高度
170
171     bool empty() { return root == nullptr; }
172
173     int size() { return sz; }
174
175 //private:
176     AVLTreeNode< T >* root;    //AVL树的根节点
177     int sz;
178
179 private:
180     void preOrder(AVLTreeNode< T >* rt) const;
181     void inOrder(AVLTreeNode< T >* rt) const;
182     void postOrder(AVLTreeNode< T >* rt) const;
183
184     void destory(AVLTreeNode< T >* &rt);
185
186     int height(AVLTreeNode< T >* rt);
187     void updateHeight(AVLTreeNode< T >* rt);
188
189     AVLTreeNode< T >* insert(AVLTreeNode< T >* &rt, T key);
190     AVLTreeNode< T >* remove(AVLTreeNode< T >* &rt, T key);
191     AVLTreeNode< T >* remove(AVLTreeNode< T >* &rt, AVLTreeNode< T >* pdel); //删除AVL树中节点pdel,并返回被删除的节点
192
193     AVLTreeNode< T >* minimum(AVLTreeNode< T >* rt) const;
194     AVLTreeNode< T >* maximum(AVLTreeNode< T >* rt) const;
195
196     AVLTreeNode< T >* search_recurse(AVLTreeNode< T >* rt, T key) const;
197     AVLTreeNode< T >* search_iterator(AVLTreeNode< T >* rt, T key) const;
198
199     AVLTreeNode< T >* L_Rotation(AVLTreeNode< T >* rt);        //单旋:左旋操作
200     AVLTreeNode< T >* R_Rotation(AVLTreeNode< T >* rt);        //单旋:右旋操作
201     AVLTreeNode< T >* LR_Rotation(AVLTreeNode< T >* rt);    //双旋:先左旋后右旋操作
202     AVLTreeNode< T >* RL_Rotation(AVLTreeNode< T >* rt);    //双旋:先右旋后左旋操作
203
204 };
205
206 /*返回一棵树的高度*/
207 template < typename T >
208 int AVLTree< T >::height(AVLTreeNode< T >* rt) {
209     if (rt != nullptr) return rt->height;
210     return 0;                                                                //如果是空树,高度为0
211 };
212
213 template < typename T >
214 void AVLTree< T >::updateHeight(AVLTreeNode< T >* rt) {
215     rt->height = max(height(rt->lchild), height(rt->rchild)) + 1;
216 }
217
218 /*左旋转操作*/
219 /*rt为最小失衡子树的根节点*/
220 /*返回旋转后的根节点*/
221 template < typename T >
222 AVLTreeNode< T >* AVLTree< T >::L_Rotation(AVLTreeNode< T >* rt) {
223     AVLTreeNode< T >* rc = rt->rchild;
224     rt->rchild = rc->lchild;
225     rc->lchild = rt;
226
227     updateHeight(rt);
228     updateHeight(rc);
229
230     return rc;
231 };
232
233 /*右旋转操作*/
234 /*rt为最小失衡子树的根节点*/
235 /*返回旋转后的根节点*/
236 template < typename  T >
237 AVLTreeNode< T >* AVLTree< T >::R_Rotation(AVLTreeNode< T >* rt) {
238     AVLTreeNode< T >* lc = rt->lchild;
239     rt->lchild = lc->rchild;
240     lc->rchild = rt;
241
242     updateHeight(rt);
243     updateHeight(lc);
244
245     return lc;
246 };
247
248 /*先右旋再左旋*/
249 /*rt为最小失衡子树的根节点*/
250 /*返回旋转后的根节点*/
251 template < typename T >
252 AVLTreeNode< T >* AVLTree< T >::RL_Rotation(AVLTreeNode< T >* rt) {
253     rt->rchild = R_Rotation(rt->rchild);
254     return L_Rotation(rt);
255 };
256
257 /*先左后右做旋转*/
258 /*rt为最小失衡子树的根节点*/
259 /*返回旋转后的根节点*/
260 template < typename T >
261 AVLTreeNode< T >* AVLTree< T >::LR_Rotation(AVLTreeNode< T >* rt) {
262     rt->lchild = L_Rotation(rt->lchild);
263     return R_Rotation(rt);
264 };
265
266 /*插入操作*/
267 /*递归地进行插入*/
268 /*返回插入后的根节点*/
269 template < typename T >
270 AVLTreeNode< T >* AVLTree< T >::insert(AVLTreeNode< T >* &rt, T key) {
271     if (rt == nullptr) { //寻找到插入的位置
272         rt = new AVLTreeNode< T >(key, nullptr, nullptr);
273         ++sz;
274     }
275     else if (key > rt->key) { //插入值比当前结点值大,插入到当前结点的右子树上
276         rt->rchild = insert(rt->rchild, key);
277         if (height(rt->rchild) - height(rt->lchild) == 2) { //插入后出现失衡
278             if (key > rt->rchild->key) rt = L_Rotation(rt); // RR型,左旋
279             else if (key < rt->rchild->key) rt = RL_Rotation(rt); // RL型,先右再左旋转
280         }
281     }
282     else if (key < rt->key) { //插入值比当前节点值小,插入到当前结点的左子树上
283         rt->lchild = insert(rt->lchild, key);
284         if (height(rt->lchild) - height(rt->rchild) == 2) { //如果插入导致失衡
285             if (key < rt->lchild->key) rt = R_Rotation(rt); // LL型,右旋
286             else if (key > rt->lchild->key) rt = LR_Rotation(rt); // LR型,先左后右旋转
287         }
288     }
289     else {
290         ++rt->num;
291         ++sz;
292     }
293     updateHeight(rt);
294     return rt;
295 };
296
297 /*删除指定元素*/
298 template < typename T >
299 AVLTreeNode< T >* AVLTree< T >::remove(AVLTreeNode< T >* &rt, T key) {
300     if (rt != nullptr) {
301         if (key == rt->key) {
302             if(rt->num > 1) {
303                 --rt->num;
304                 --sz;
305             }
306             //因AVL也是二叉排序树,删除节点要维护其二叉排序树的条件
307             else if (rt->lchild != nullptr && rt->rchild != nullptr) {       //若左右都不为空
308                 // 左子树比右子树高,在左子树上选择节点进行替换
309                 if (height(rt->lchild) > height(rt->rchild)) {
310                     //使用左子树最大节点来代替被删节点,而删除该最大节点
311                     int tmp = maximum(rt->lchild)->key;        //左子树最大节点值
312                     rt->key = tmp;                              //将最大节点的值覆盖当前结点
313                     rt->lchild = remove(rt->lchild, tmp);    //递归地删除最大节点,因为沿途所有节点又要判断平衡性
314                 }
315                 else { //在右子树上选择节点进行替换
316                     //使用最小节点来代替被删节点,而删除该最小节点
317                     int tmp = minimum(rt->rchild)->key;        //右子树的最小节点值
318                     rt->key = tmp;                                //将最小节点值覆盖当前结点
319                     rt->rchild = remove(rt->rchild, tmp);    //递归地删除最小节点
320                 }
321             }
322             else {
323                 AVLTreeNode< T >* ptmp = rt;
324                 if (rt->lchild != nullptr) rt = rt->lchild;
325                 else if (rt->rchild != nullptr) rt = rt->rchild;
326                 delete ptmp;
327                 --sz;
328                 return nullptr;
329             }
330         }
331         else if (key > rt->key) { //要删除的节点比当前节点大,则在右子树进行删除
332             rt->rchild =  remove(rt->rchild, key);
333             //删除右子树节点导致不平衡:相当于情况二或情况四
334             if (height(rt->lchild) - height(rt->rchild) == 2) {
335                 //相当于在左子树上插入右节点造成的失衡(情况四)
336                 if (height(rt->lchild->rchild) > height(rt->lchild->lchild)) rt = leftRightRotation(rt);
337                 //相当于在左子树上插入左节点造成的失衡(情况二)
338                 else rt = rightRotation(rt);
339             }
340         }
341         else if (key < rt->key) { //要删除的节点比当前节点小,则在左子树进行删除
342             rt->lchild= remove(rt->lchild, key);
343              //删除左子树节点导致不平衡:相当于情况三或情况一
344             if (height(rt->rchild) - height(rt->lchild) == 2) {
345                 //相当于在右子树上插入左节点造成的失衡(情况三)
346                 if (height(rt->rchild->lchild) > height(rt->rchild->rchild)) rt = rightLeftRotation(rt);
347                 //相当于在右子树上插入右节点造成的失衡(情况一)
348                 else rt = leftRotation(rt);
349             }
350         }
351         return rt;
352     }
353     return nullptr;
354 };
355
356 /*递归查找指定元素*/
357 template < typename T >
358 AVLTreeNode< T >* AVLTree< T >::search_recurse(AVLTreeNode< T >* rt, T key) const {
359     if (rt != nullptr) {
360         if (key > rt->key) return search_recurse(rt->rchild,key);
361         else if(key < rt->key) return search_recurse(rt->lchild,key);
362         return rt;
363     }
364     return nullptr;
365 };
366
367 /*非递归查找指定元素*/
368 template < typename T >
369 AVLTreeNode< T >* AVLTree< T >::search_iterator(AVLTreeNode< T >* rt, T key) const {
370     while (rt != nullptr) {
371         if (key > rt->key) rt = rt->rchild;
372         else if (key < rt->key) rt = rt->lchild;
373         else return rt;
374     }
375     return nullptr;
376 };
377
378 /*先序遍历*/
379 template < typename T >
380 void AVLTree< T >::preOrder(AVLTreeNode< T >* rt) const {
381     if (rt != nullptr) {
382         cout << rt->key << endl;
383         preOrder(rt->lchild);
384         preOrder(rt->rchild);
385     }
386 };
387
388 /*中序遍历*/
389 template < typename T >
390 void AVLTree< T >::inOrder(AVLTreeNode< T >* rt) const {
391     if (rt != nullptr) {
392         inOrder(rt->lchild);
393         cout << rt->key << endl;
394         inOrder(rt->rchild);
395     }
396 };
397
398 /*后序遍历*/
399 template < typename T >
400 void AVLTree< T >::postOrder(AVLTreeNode< T >* rt) const {
401     if (rt != nullptr) {
402         postOrder(rt->lchild);
403         postOrder(rt->rchild);
404         cout << rt->key << endl;
405     }
406 }
407
408 /*销毁AVL树*/
409 template < typename T >
410 void AVLTree< T >::destory(AVLTreeNode< T >* & rt) {
411     if (rt != nullptr) {
412         destory(rt->lchild);    //递归销毁左子树
413         destory(rt->rchild);    //递归销毁右子树
414         delete rt;              //销毁根节点
415         rt = nullptr;
416     }
417 };
418
419 /*返回树中最大节点值*/
420 template < typename T >
421 AVLTreeNode< T >* AVLTree< T >::maximum(AVLTreeNode< T >* rt) const {
422     if (rt != nullptr) {
423         while (rt->rchild != nullptr) rt = rt->rchild;
424         return rt;
425     }
426     return nullptr;
427 };
428
429 template< typename T >
430 T AVLTree< T >::maximum() {
431     assert(this->empty());
432     AVLTreeNode< T >* presult = maximum(root);
433     if (presult != nullptr) return presult->key;
434 };
435
436 /*返回树中最小节点值*/
437 template < typename T >
438 AVLTreeNode< T >* AVLTree< T >::minimum(AVLTreeNode< T >* rt) const {
439     if (rt != nullptr) {
440         while (rt->lchild != nullptr) rt = rt->lchild;
441         return rt;
442     }
443     return nullptr;
444 };
445
446 template < typename T >
447 T AVLTree< T >::minimum() {
448     assert(this->empty());
449     AVLTreeNode< T >* presult = minimum(root);
450     if (presult != nullptr) return presult->key;
451 };
452
453 int N;
454 AVLTree< int > avl;
455
456 int main(){
457     //freopen("MyOutput.txt","w",stdout);
458     //freopen("input.txt","r",stdin);
459     INIT();
460     cin >> N;
461     For(i, 1, N) {
462         int x;
463         cin >> x;
464         avl.insert(x);
465     }
466     cout << avl.root->key << endl;
467     return 0;
468 }

原文地址:https://www.cnblogs.com/zaq19970105/p/11330860.html

时间: 2024-08-29 12:53:50

SDUTOJ 3374 数据结构实验之查找二:平衡二叉树的相关文章

SDUT 3374 数据结构实验之查找二:平衡二叉树

数据结构实验之查找二:平衡二叉树 Time Limit: 400MS Memory Limit: 65536KB Submit Statistic Problem Description 根据给定的输入序列建立一棵平衡二叉树,求出建立的平衡二叉树的树根. Input 输入一组测试数据.数据的第1行给出一个正整数N(n <= 20),N表示输入序列的元素个数:第2行给出N个正整数,按数据给定顺序建立平衡二叉树. Output 输出平衡二叉树的树根. Example Input 5 88 70 61

数据结构实验之图论二:基于邻接表的广度优先搜索遍历

数据结构实验之图论二:基于邻接表的广度优先搜索遍历 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索(BFS)遍历,输出从某个顶点出发的遍历序列.(同一个结点的同层邻接点,节点编号小的优先遍历) 输入 输入第一行为整数n(0< n <100),表示数据的组数. 对于每组数据,第一行是三个整数k,m,t(0<k<100,0<m<(k-1)*k/2,

SDUT 2142 【TEST】数据结构实验之图论二:基于邻接表的广度优先搜索遍历

数据结构实验之图论二:基于邻接表的广度优先搜索遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Description 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索(BFS)遍历,输出从某个顶点出发的遍历序列.(同一个结点的同层邻接点,节点编号小的优先遍历) Input 输入第一行为整数n(0< n <100),表示数据的组数.对于每组数据,第一行是三个整数k,m,t(0<

SDUT 3341 数据结构实验之二叉树二:遍历二叉树

数据结构实验之二叉树二:遍历二叉树 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 已知二叉树的一个按先序遍历输入的字符序列,如abc,,de,g,,f,,, (其中,表示空结点).请建立二叉树并按中序和后序的方式遍历该二叉树. Input 连续输入多组数据,每组数据输入一个长度小于50个字符的字符串. Output 每组输入数据对应输出2行:第1行输出中序遍历序列:第2行输出后序遍历序列

SDUT 3376 数据结构实验之查找四:二分查找

数据结构实验之查找四:二分查找 Time Limit: 20MS Memory Limit: 65536KB Submit Statistic Problem Description 在一个给定的无重复元素的递增序列里,查找与给定关键字相同的元素,若存在则输出找到的位置,不存在输出-1. Input 一组输入数据,输入数据第一行首先输入两个正整数n ( n < = 10^6 )和m ( m < = 10^4 ),n是数组中数据元素个数,随后连续输入n个正整数,输入的数据保证数列递增.随后m行输

SDUT 3375 数据结构实验之查找三:树的种类统计

数据结构实验之查找三:树的种类统计 Time Limit: 400MS Memory Limit: 65536KB Submit Statistic Problem Description 随着卫星成像技术的应用,自然资源研究机构可以识别每一个棵树的种类.请编写程序帮助研究人员统计每种树的数量,计算每种树占总数的百分比. Input 输入一组测试数据.数据的第1行给出一个正整数N (n <= 100000),N表示树的数量:随后N行,每行给出卫星观测到的一棵树的种类名称,树的名称是一个不超过20

SDUT 3399 数据结构实验之排序二:交换排序

数据结构实验之排序二:交换排序 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 冒泡排序和快速排序都是基于"交换"进行的排序方法,你的任务是对题目给定的N个(长整型范围内的)整数从小到大排序,输出用冒泡和快排对这N个数排序分别需要进行的数据交换次数. Input 连续多组输入数据,每组数据第一行给出正整数N(N ≤ 10^5),随后给出N个整数,数字间以空格分隔. Output

数据结构实验之栈二:一般算术表达式转换成后缀式

数据结构实验之栈二:一般算术表达式转换成后缀式 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 对于一个基于二元运算符的算术表达式,转换为对应的后缀式,并输出之. 输入 输入一个算术表达式,以'#'字符作为结束标志. 输出 输出该表达式转换所得到的后缀式. 示例输入 a*b+(c-d/e)*f# 示例输出 ab*cde/-f*+ 提示 来源 示例程序 由一般是求后缀式: 1.设立暂时存放运算符的栈: 2.设表达式的结束符为"#

SDUT 3379 数据结构实验之查找七:线性之哈希表

数据结构实验之查找七:线性之哈希表 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 根据给定的一系列整数关键字和素数p,用除留余数法定义hash函数H(Key)=Key%p,将关键字映射到长度为p的哈希表中,用线性探测法解决冲突.重复关键字放在hash表中的同一位置. Input 连续输入多组数据,每组输入数据第一行为两个正整数N(N <= 1000)和p(p >= N的最小素数),N是