zoukankan      html  css  js  c++  java
  • 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] << " 
    "[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 << "]" << "
    ";
     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 }
    View Code
  • 相关阅读:
    SSLZYC NOIP
    SSLZYC 懒惰的奶牛①
    SSLZYC 小麦高度
    Pythonlog() 函数
    详细解读Python中的__init__()方法
    详细解读Python中的__init__()方法
    Linux软件安装中RPM与YUM 区别和联系
    Linux软件安装中RPM与YUM 区别和联系
    【我的物联网成长记】设备如何进行选型?
    【我的物联网成长记】设备如何进行选型?
  • 原文地址:https://www.cnblogs.com/zaq19970105/p/11330860.html
Copyright © 2011-2022 走看看