zoukankan      html  css  js  c++  java
  • 5、【树形结构】AVL树

    一、AVL树的介绍

    AVL树是高度平衡的而二叉树。

    它的特点是:AVL树中任何节点的两个子树的高度最大差别为1。

    二、AVL树的C++实现

    1. 节点

    1.1 AVL树节点

     1 template <class T>
     2 class AVLTreeNode{
     3     public:
     4         T key;                // 关键字(键值)
     5         int height;         // 高度
     6         AVLTreeNode *left;    // 左孩子
     7         AVLTreeNode *right;    // 右孩子
     8 
     9         AVLTreeNode(T value, AVLTreeNode *l, AVLTreeNode *r):
    10             key(value), height(0),left(l),right(r) {}
    11 };

    AVLTreeNode是AVL树的节点类,它包括的几个组成对象:
      (1) key -- 是关键字,是用来对AVL树的节点进行排序的。
      (2) left -- 是左孩子。
      (3) right -- 是右孩子。
      (4) height -- 是高度。

    1.2 AVL树

     1 template <class T>
     2 class AVLTree {
     3     private:
     4         AVLTreeNode<T> *mRoot;    // 根结点
     5 
     6     public:
     7         AVLTree();
     8         ~AVLTree();
     9 
    10         // 获取树的高度
    11         int height();
    12         // 获取树的高度
    13         int max(int a, int b);
    14 
    15         // 前序遍历"AVL树"
    16         void preOrder();
    17         // 中序遍历"AVL树"
    18         void inOrder();
    19         // 后序遍历"AVL树"
    20         void postOrder();
    21 
    22         // (递归实现)查找"AVL树"中键值为key的节点
    23         AVLTreeNode<T>* search(T key);
    24         // (非递归实现)查找"AVL树"中键值为key的节点
    25         AVLTreeNode<T>* iterativeSearch(T key);
    26 
    27         // 查找最小结点:返回最小结点的键值。
    28         T minimum();
    29         // 查找最大结点:返回最大结点的键值。
    30         T maximum();
    31 
    32         // 将结点(key为节点键值)插入到AVL树中
    33         void insert(T key);
    34 
    35         // 删除结点(key为节点键值)
    36         void remove(T key);
    37 
    38         // 销毁AVL树
    39         void destroy();
    40 
    41         // 打印AVL树
    42         void print();
    43     private:
    44         // 获取树的高度
    45         int height(AVLTreeNode<T>* tree) ;
    46 
    47         // 前序遍历"AVL树"
    48         void preOrder(AVLTreeNode<T>* tree) const;
    49         // 中序遍历"AVL树"
    50         void inOrder(AVLTreeNode<T>* tree) const;
    51         // 后序遍历"AVL树"
    52         void postOrder(AVLTreeNode<T>* tree) const;
    53 
    54         // (递归实现)查找"AVL树x"中键值为key的节点
    55         AVLTreeNode<T>* search(AVLTreeNode<T>* x, T key) const;
    56         // (非递归实现)查找"AVL树x"中键值为key的节点
    57         AVLTreeNode<T>* iterativeSearch(AVLTreeNode<T>* x, T key) const;
    58 
    59         // 查找最小结点:返回tree为根结点的AVL树的最小结点。
    60         AVLTreeNode<T>* minimum(AVLTreeNode<T>* tree);
    61         // 查找最大结点:返回tree为根结点的AVL树的最大结点。
    62         AVLTreeNode<T>* maximum(AVLTreeNode<T>* tree);
    63 
    64         // LL:左左对应的情况(左单旋转)。
    65         AVLTreeNode<T>* leftLeftRotation(AVLTreeNode<T>* k2);
    66 
    67         // RR:右右对应的情况(右单旋转)。
    68         AVLTreeNode<T>* rightRightRotation(AVLTreeNode<T>* k1);
    69 
    70         // LR:左右对应的情况(左双旋转)。
    71         AVLTreeNode<T>* leftRightRotation(AVLTreeNode<T>* k3);
    72 
    73         // RL:右左对应的情况(右双旋转)。
    74         AVLTreeNode<T>* rightLeftRotation(AVLTreeNode<T>* k1);
    75 
    76         // 将结点(z)插入到AVL树(tree)中
    77         AVLTreeNode<T>* insert(AVLTreeNode<T>* &tree, T key);
    78 
    79         // 删除AVL树(tree)中的结点(z),并返回被删除的结点
    80         AVLTreeNode<T>* remove(AVLTreeNode<T>* &tree, AVLTreeNode<T>* z);
    81 
    82         // 销毁AVL树
    83         void destroy(AVLTreeNode<T>* &tree);
    84 
    85         // 打印AVL树
    86         void print(AVLTreeNode<T>* tree, T key, int direction);
    87 };

    AVLTree是AVL树对应的类。它包含AVL树的根节点mRoot和AVL树的基本操作接口。需要说明的是:AVLTree中重载了许多函数。重载的目的是区分内部接口和外部接口,例如insert()函数而言,insert(tree, key)是内部接口,而insert(key)是外部接口。

    1.2 树的高度

     1 /*
     2  * 获取树的高度
     3  */
     4 template <class T>
     5 int AVLTree<T>::height(AVLTreeNode<T>* tree) 
     6 {
     7     if (tree != NULL)
     8         return tree->height;
     9 
    10     return 0;
    11 }
    12 
    13 template <class T>
    14 int AVLTree<T>::height() 
    15 {
    16     return height(mRoot);
    17 }

    1.3 比较大小

    /*
     * 比较两个值的大小
     */
    template <class T>
    int AVLTree<T>::max(int a, int b) 
    {
        return a>b ? a : b;
    }

    如果在AVL树中进行插入或删除节点后,可能导致AVL树失去平衡。AVL失去平衡之后,可以通过旋转使其恢复平衡。具体的旋转原理和实现参见:http://www.cnblogs.com/skywang12345/p/3577360.html

    注意关于AVL树的"前序遍历"、"中序遍历"、"后序遍历"、"最大值"、"最小值"、"查找"、"打印"、"销毁"等接口与"二叉查找树"基本一样,

    【完整示例】

    AVLTree.h

      1 #ifndef _AVL_TREE_HPP_
      2 #define _AVL_TREE_HPP_
      3 
      4 #include <iomanip>
      5 #include <iostream>
      6 using namespace std;
      7 
      8 template <class T>
      9 class AVLTreeNode{
     10     public:
     11         T key;                // 关键字(键值)
     12         int height;         // 高度
     13         AVLTreeNode *left;    // 左孩子
     14         AVLTreeNode *right;    // 右孩子
     15 
     16         AVLTreeNode(T value, AVLTreeNode *l, AVLTreeNode *r):
     17             key(value), height(0),left(l),right(r) {}
     18 };
     19 
     20 template <class T>
     21 class AVLTree {
     22     private:
     23         AVLTreeNode<T> *mRoot;    // 根结点
     24 
     25     public:
     26         AVLTree();
     27         ~AVLTree();
     28 
     29         // 获取树的高度
     30         int height();
     31         // 获取树的高度
     32         int max(int a, int b);
     33 
     34         // 前序遍历"AVL树"
     35         void preOrder();
     36         // 中序遍历"AVL树"
     37         void inOrder();
     38         // 后序遍历"AVL树"
     39         void postOrder();
     40 
     41         // (递归实现)查找"AVL树"中键值为key的节点
     42         AVLTreeNode<T>* search(T key);
     43         // (非递归实现)查找"AVL树"中键值为key的节点
     44         AVLTreeNode<T>* iterativeSearch(T key);
     45 
     46         // 查找最小结点:返回最小结点的键值。
     47         T minimum();
     48         // 查找最大结点:返回最大结点的键值。
     49         T maximum();
     50 
     51         // 将结点(key为节点键值)插入到AVL树中
     52         void insert(T key);
     53 
     54         // 删除结点(key为节点键值)
     55         void remove(T key);
     56 
     57         // 销毁AVL树
     58         void destroy();
     59 
     60         // 打印AVL树
     61         void print();
     62     private:
     63         // 获取树的高度
     64         int height(AVLTreeNode<T>* tree) ;
     65 
     66         // 前序遍历"AVL树"
     67         void preOrder(AVLTreeNode<T>* tree) const;
     68         // 中序遍历"AVL树"
     69         void inOrder(AVLTreeNode<T>* tree) const;
     70         // 后序遍历"AVL树"
     71         void postOrder(AVLTreeNode<T>* tree) const;
     72 
     73         // (递归实现)查找"AVL树x"中键值为key的节点
     74         AVLTreeNode<T>* search(AVLTreeNode<T>* x, T key) const;
     75         // (非递归实现)查找"AVL树x"中键值为key的节点
     76         AVLTreeNode<T>* iterativeSearch(AVLTreeNode<T>* x, T key) const;
     77 
     78         // 查找最小结点:返回tree为根结点的AVL树的最小结点。
     79         AVLTreeNode<T>* minimum(AVLTreeNode<T>* tree);
     80         // 查找最大结点:返回tree为根结点的AVL树的最大结点。
     81         AVLTreeNode<T>* maximum(AVLTreeNode<T>* tree);
     82 
     83         // LL:左左对应的情况(左单旋转)。
     84         AVLTreeNode<T>* leftLeftRotation(AVLTreeNode<T>* k2);
     85 
     86         // RR:右右对应的情况(右单旋转)。
     87         AVLTreeNode<T>* rightRightRotation(AVLTreeNode<T>* k1);
     88 
     89         // LR:左右对应的情况(左双旋转)。
     90         AVLTreeNode<T>* leftRightRotation(AVLTreeNode<T>* k3);
     91 
     92         // RL:右左对应的情况(右双旋转)。
     93         AVLTreeNode<T>* rightLeftRotation(AVLTreeNode<T>* k1);
     94 
     95         // 将结点(z)插入到AVL树(tree)中
     96         AVLTreeNode<T>* insert(AVLTreeNode<T>* &tree, T key);
     97 
     98         // 删除AVL树(tree)中的结点(z),并返回被删除的结点
     99         AVLTreeNode<T>* remove(AVLTreeNode<T>* &tree, AVLTreeNode<T>* z);
    100 
    101         // 销毁AVL树
    102         void destroy(AVLTreeNode<T>* &tree);
    103 
    104         // 打印AVL树
    105         void print(AVLTreeNode<T>* tree, T key, int direction);
    106 };
    107 
    108 /*
    109  * 构造函数
    110  */
    111 template <class T>
    112 AVLTree<T>::AVLTree():mRoot(NULL)
    113 {
    114 }
    115 
    116 /*
    117  * 析构函数
    118  */
    119 template <class T>
    120 AVLTree<T>::~AVLTree()
    121 {
    122     destroy(mRoot);
    123 }
    124 
    125 /*
    126  * 获取树的高度
    127  */
    128 template <class T>
    129 int AVLTree<T>::height(AVLTreeNode<T>* tree)
    130 {
    131     if (tree != NULL)
    132         return tree->height;
    133 
    134     return 0;
    135 }
    136 
    137 template <class T>
    138 int AVLTree<T>::height()
    139 {
    140     return height(mRoot);
    141 }
    142 /*
    143  * 比较两个值的大小
    144  */
    145 template <class T>
    146 int AVLTree<T>::max(int a, int b)
    147 {
    148     return a>b ? a : b;
    149 }
    150 
    151 /*
    152  * 前序遍历"AVL树"
    153  */
    154 template <class T>
    155 void AVLTree<T>::preOrder(AVLTreeNode<T>* tree) const
    156 {
    157     if(tree != NULL)
    158     {
    159         cout<< tree->key << " " ;
    160         preOrder(tree->left);
    161         preOrder(tree->right);
    162     }
    163 }
    164 
    165 template <class T>
    166 void AVLTree<T>::preOrder()
    167 {
    168     preOrder(mRoot);
    169 }
    170 
    171 /*
    172  * 中序遍历"AVL树"
    173  */
    174 template <class T>
    175 void AVLTree<T>::inOrder(AVLTreeNode<T>* tree) const
    176 {
    177     if(tree != NULL)
    178     {
    179         inOrder(tree->left);
    180         cout<< tree->key << " " ;
    181         inOrder(tree->right);
    182     }
    183 }
    184 
    185 template <class T>
    186 void AVLTree<T>::inOrder()
    187 {
    188     inOrder(mRoot);
    189 }
    190 
    191 /*
    192  * 后序遍历"AVL树"
    193  */
    194 template <class T>
    195 void AVLTree<T>::postOrder(AVLTreeNode<T>* tree) const
    196 {
    197     if(tree != NULL)
    198     {
    199         postOrder(tree->left);
    200         postOrder(tree->right);
    201         cout<< tree->key << " " ;
    202     }
    203 }
    204 
    205 template <class T>
    206 void AVLTree<T>::postOrder()
    207 {
    208     postOrder(mRoot);
    209 }
    210 
    211 /*
    212  * (递归实现)查找"AVL树x"中键值为key的节点
    213  */
    214 template <class T>
    215 AVLTreeNode<T>* AVLTree<T>::search(AVLTreeNode<T>* x, T key) const
    216 {
    217     if (x==NULL || x->key==key)
    218         return x;
    219 
    220     if (key < x->key)
    221         return search(x->left, key);
    222     else
    223         return search(x->right, key);
    224 }
    225 
    226 template <class T>
    227 AVLTreeNode<T>* AVLTree<T>::search(T key)
    228 {
    229     return search(mRoot, key);
    230 }
    231 
    232 /*
    233  * (非递归实现)查找"AVL树x"中键值为key的节点
    234  */
    235 template <class T>
    236 AVLTreeNode<T>* AVLTree<T>::iterativeSearch(AVLTreeNode<T>* x, T key) const
    237 {
    238     while ((x!=NULL) && (x->key!=key))
    239     {
    240         if (key < x->key)
    241             x = x->left;
    242         else
    243             x = x->right;
    244     }
    245 
    246     return x;
    247 }
    248 
    249 template <class T>
    250 AVLTreeNode<T>* AVLTree<T>::iterativeSearch(T key)
    251 {
    252     return iterativeSearch(mRoot, key);
    253 }
    254 
    255 /*
    256  * 查找最小结点:返回tree为根结点的AVL树的最小结点。
    257  */
    258 template <class T>
    259 AVLTreeNode<T>* AVLTree<T>::minimum(AVLTreeNode<T>* tree)
    260 {
    261     if (tree == NULL)
    262         return NULL;
    263 
    264     while(tree->left != NULL)
    265         tree = tree->left;
    266     return tree;
    267 }
    268 
    269 template <class T>
    270 T AVLTree<T>::minimum()
    271 {
    272     AVLTreeNode<T> *p = minimum(mRoot);
    273     if (p != NULL)
    274         return p->key;
    275 
    276     return (T)NULL;
    277 }
    278 
    279 /*
    280  * 查找最大结点:返回tree为根结点的AVL树的最大结点。
    281  */
    282 template <class T>
    283 AVLTreeNode<T>* AVLTree<T>::maximum(AVLTreeNode<T>* tree)
    284 {
    285     if (tree == NULL)
    286         return NULL;
    287 
    288     while(tree->right != NULL)
    289         tree = tree->right;
    290     return tree;
    291 }
    292 
    293 template <class T>
    294 T AVLTree<T>::maximum()
    295 {
    296     AVLTreeNode<T> *p = maximum(mRoot);
    297     if (p != NULL)
    298         return p->key;
    299 
    300     return (T)NULL;
    301 }
    302 
    303 /*
    304  * LL:左左对应的情况(左单旋转)。
    305  *
    306  * 返回值:旋转后的根节点
    307  */
    308 template <class T>
    309 AVLTreeNode<T>* AVLTree<T>::leftLeftRotation(AVLTreeNode<T>* k2)
    310 {
    311     AVLTreeNode<T>* k1;
    312 
    313     k1 = k2->left;
    314     k2->left = k1->right;
    315     k1->right = k2;
    316 
    317     k2->height = max( height(k2->left), height(k2->right)) + 1;
    318     k1->height = max( height(k1->left), k2->height) + 1;
    319 
    320     return k1;
    321 }
    322 
    323 /*
    324  * RR:右右对应的情况(右单旋转)。
    325  *
    326  * 返回值:旋转后的根节点
    327  */
    328 template <class T>
    329 AVLTreeNode<T>* AVLTree<T>::rightRightRotation(AVLTreeNode<T>* k1)
    330 {
    331     AVLTreeNode<T>* k2;
    332 
    333     k2 = k1->right;
    334     k1->right = k2->left;
    335     k2->left = k1;
    336 
    337     k1->height = max( height(k1->left), height(k1->right)) + 1;
    338     k2->height = max( height(k2->right), k1->height) + 1;
    339 
    340     return k2;
    341 }
    342 
    343 /*
    344  * LR:左右对应的情况(左双旋转)。
    345  *
    346  * 返回值:旋转后的根节点
    347  */
    348 template <class T>
    349 AVLTreeNode<T>* AVLTree<T>::leftRightRotation(AVLTreeNode<T>* k3)
    350 {
    351     k3->left = rightRightRotation(k3->left);
    352 
    353     return leftLeftRotation(k3);
    354 }
    355 
    356 /*
    357  * RL:右左对应的情况(右双旋转)。
    358  *
    359  * 返回值:旋转后的根节点
    360  */
    361 template <class T>
    362 AVLTreeNode<T>* AVLTree<T>::rightLeftRotation(AVLTreeNode<T>* k1)
    363 {
    364     k1->right = leftLeftRotation(k1->right);
    365 
    366     return rightRightRotation(k1);
    367 }
    368 
    369 /*
    370  * 将结点插入到AVL树中,并返回根节点
    371  *
    372  * 参数说明:
    373  *     tree AVL树的根结点
    374  *     key 插入的结点的键值
    375  * 返回值:
    376  *     根节点
    377  */
    378 template <class T>
    379 AVLTreeNode<T>* AVLTree<T>::insert(AVLTreeNode<T>* &tree, T key)
    380 {
    381     if (tree == NULL)
    382     {
    383         // 新建节点
    384         tree = new AVLTreeNode<T>(key, NULL, NULL);
    385         if (tree==NULL)
    386         {
    387             cout << "ERROR: create avltree node failed!" << endl;
    388             return NULL;
    389         }
    390     }
    391     else if (key < tree->key) // 应该将key插入到"tree的左子树"的情况
    392     {
    393         tree->left = insert(tree->left, key);
    394         // 插入节点后,若AVL树失去平衡,则进行相应的调节。
    395         if (height(tree->left) - height(tree->right) == 2)
    396         {
    397             if (key < tree->left->key)
    398                 tree = leftLeftRotation(tree);
    399             else
    400                 tree = leftRightRotation(tree);
    401         }
    402     }
    403     else if (key > tree->key) // 应该将key插入到"tree的右子树"的情况
    404     {
    405         tree->right = insert(tree->right, key);
    406         // 插入节点后,若AVL树失去平衡,则进行相应的调节。
    407         if (height(tree->right) - height(tree->left) == 2)
    408         {
    409             if (key > tree->right->key)
    410                 tree = rightRightRotation(tree);
    411             else
    412                 tree = rightLeftRotation(tree);
    413         }
    414     }
    415     else //key == tree->key)
    416     {
    417         cout << "添加失败:不允许添加相同的节点!" << endl;
    418     }
    419 
    420     tree->height = max( height(tree->left), height(tree->right)) + 1;
    421 
    422     return tree;
    423 }
    424 
    425 template <class T>
    426 void AVLTree<T>::insert(T key)
    427 {
    428     insert(mRoot, key);
    429 }
    430 
    431 /*
    432  * 删除结点(z),返回根节点
    433  *
    434  * 参数说明:
    435  *     tree AVL树的根结点
    436  *     z 待删除的结点
    437  * 返回值:
    438  *     根节点
    439  */
    440 template <class T>
    441 AVLTreeNode<T>* AVLTree<T>::remove(AVLTreeNode<T>* &tree, AVLTreeNode<T>* z)
    442 {
    443     // 根为空 或者 没有要删除的节点,直接返回NULL。
    444     if (tree==NULL || z==NULL)
    445         return NULL;
    446 
    447     if (z->key < tree->key)        // 待删除的节点在"tree的左子树"中
    448     {
    449         tree->left = remove(tree->left, z);
    450         // 删除节点后,若AVL树失去平衡,则进行相应的调节。
    451         if (height(tree->right) - height(tree->left) == 2)
    452         {
    453             AVLTreeNode<T> *r =  tree->right;
    454             if (height(r->left) > height(r->right))
    455                 tree = rightLeftRotation(tree);
    456             else
    457                 tree = rightRightRotation(tree);
    458         }
    459     }
    460     else if (z->key > tree->key)// 待删除的节点在"tree的右子树"中
    461     {
    462         tree->right = remove(tree->right, z);
    463         // 删除节点后,若AVL树失去平衡,则进行相应的调节。
    464         if (height(tree->left) - height(tree->right) == 2)
    465         {
    466             AVLTreeNode<T> *l =  tree->left;
    467             if (height(l->right) > height(l->left))
    468                 tree = leftRightRotation(tree);
    469             else
    470                 tree = leftLeftRotation(tree);
    471         }
    472     }
    473     else    // tree是对应要删除的节点。
    474     {
    475         // tree的左右孩子都非空
    476         if ((tree->left!=NULL) && (tree->right!=NULL))
    477         {
    478             if (height(tree->left) > height(tree->right))
    479             {
    480                 // 如果tree的左子树比右子树高;
    481                 // 则(01)找出tree的左子树中的最大节点
    482                 //   (02)将该最大节点的值赋值给tree。
    483                 //   (03)删除该最大节点。
    484                 // 这类似于用"tree的左子树中最大节点"做"tree"的替身;
    485                 // 采用这种方式的好处是:删除"tree的左子树中最大节点"之后,AVL树仍然是平衡的。
    486                 AVLTreeNode<T>* max = maximum(tree->left);
    487                 tree->key = max->key;
    488                 tree->left = remove(tree->left, max);
    489             }
    490             else
    491             {
    492                 // 如果tree的左子树不比右子树高(即它们相等,或右子树比左子树高1)
    493                 // 则(01)找出tree的右子树中的最小节点
    494                 //   (02)将该最小节点的值赋值给tree。
    495                 //   (03)删除该最小节点。
    496                 // 这类似于用"tree的右子树中最小节点"做"tree"的替身;
    497                 // 采用这种方式的好处是:删除"tree的右子树中最小节点"之后,AVL树仍然是平衡的。
    498                 AVLTreeNode<T>* min = maximum(tree->right);
    499                 tree->key = min->key;
    500                 tree->right = remove(tree->right, min);
    501             }
    502         }
    503         else
    504         {
    505             AVLTreeNode<T>* tmp = tree;
    506             tree = (tree->left!=NULL) ? tree->left : tree->right;
    507             delete tmp;
    508         }
    509     }
    510 
    511     return tree;
    512 }
    513 
    514 template <class T>
    515 void AVLTree<T>::remove(T key)
    516 {
    517     AVLTreeNode<T>* z;
    518 
    519     if ((z = search(mRoot, key)) != NULL)
    520         mRoot = remove(mRoot, z);
    521 }
    522 
    523 /*
    524  * 销毁AVL树
    525  */
    526 template <class T>
    527 void AVLTree<T>::destroy(AVLTreeNode<T>* &tree)
    528 {
    529     if (tree==NULL)
    530         return ;
    531 
    532     if (tree->left != NULL)
    533         destroy(tree->left);
    534     if (tree->right != NULL)
    535         destroy(tree->right);
    536 
    537     delete tree;
    538 }
    539 
    540 template <class T>
    541 void AVLTree<T>::destroy()
    542 {
    543     destroy(mRoot);
    544 }
    545 
    546 /*
    547  * 打印"二叉查找树"
    548  *
    549  * key        -- 节点的键值
    550  * direction  --  0,表示该节点是根节点;
    551  *               -1,表示该节点是它的父结点的左孩子;
    552  *                1,表示该节点是它的父结点的右孩子。
    553  */
    554 template <class T>
    555 void AVLTree<T>::print(AVLTreeNode<T>* tree, T key, int direction)
    556 {
    557     if(tree != NULL)
    558     {
    559         if(direction==0)    // tree是根节点
    560             cout << setw(2) << tree->key << " is root" << endl;
    561         else                // tree是分支节点
    562             cout << setw(2) << tree->key << " is " << setw(2) << key << "'s "  << setw(12) << (direction==1?"right child" : "left child") << endl;
    563 
    564         print(tree->left, tree->key, -1);
    565         print(tree->right,tree->key,  1);
    566     }
    567 }
    568 
    569 template <class T>
    570 void AVLTree<T>::print()
    571 {
    572     if (mRoot != NULL)
    573         print(mRoot, mRoot->key, 0);
    574 }
    575 #endif

    main.cpp

     1 #include <iostream>
     2 #include "AVLTree.h"
     3 using namespace std;
     4 
     5 static int arr[]= {3,2,1,4,5,6,7,16,15,14,13,12,11,10,8,9};
     6 #define TBL_SIZE(a) ( (sizeof(a)) / (sizeof(a[0])) )
     7 
     8 int main()
     9 {
    10     int i,ilen;
    11     AVLTree<int>* tree=new AVLTree<int>();
    12 
    13     cout << "== 依次添加: ";
    14     ilen = TBL_SIZE(arr);
    15     for(i=0; i<ilen; i++)
    16     {
    17         cout << arr[i] <<" ";
    18         tree->insert(arr[i]);
    19     }
    20 
    21     cout << "
    == 前序遍历: ";
    22     tree->preOrder();
    23 
    24     cout << "
    == 中序遍历: ";
    25     tree->inOrder();
    26 
    27     cout << "
    == 后序遍历: ";
    28     tree->postOrder();
    29     cout << endl;
    30 
    31     cout << "== 高度: " << tree->height() << endl;
    32     cout << "== 最小值: " << tree->minimum() << endl;
    33     cout << "== 最大值: " << tree->maximum() << endl;
    34     cout << "== 树的详细信息: " << endl;
    35     tree->print();
    36 
    37     i = 8;
    38     cout << "
    == 删除根节点: " << i;
    39     tree->remove(i);
    40 
    41     cout << "
    == 高度: " << tree->height() ;
    42     cout << "
    == 中序遍历: " ;
    43     tree->inOrder();
    44     cout << "
    == 树的详细信息: " << endl;
    45     tree->print();
    46 
    47     // 销毁二叉树
    48     tree->destroy();
    49 
    50     return 0;
    51 }
  • 相关阅读:
    iOS应用崩溃日志分析
    使用Crashlytics来保存应用崩溃信息
    Mac和iOS开发资源汇总
    简单配置PonyDebugger
    程序员的工作不能用“生产效率”这个词来衡量
    使用Reveal 调试iOS应用程序
    MySQL 笔记
    flex弹性布局
    回调函数
    微信小程序开发
  • 原文地址:https://www.cnblogs.com/Long-w/p/9778430.html
Copyright © 2011-2022 走看看