SDUTOJ 3374 数据结构实验之查找二:平衡二叉树
Posted zaq19970105
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
以上是关于SDUTOJ 3374 数据结构实验之查找二:平衡二叉树的主要内容,如果未能解决你的问题,请参考以下文章