• "《算法导论》之‘树’":AVL树


      本文关于AVL树的介绍引自博文AVL树(二)之 C++的实现,与二叉查找树相同的部分则不作介绍直接引用;代码实现是在本文的基础上自己实现且继承自上一篇博文二叉查找树

    1.AVL树的介绍

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

      

      上面的两张图片,左边的是AVL树,它的任何节点的两个子树的高度差别都<=1;而右边的不是AVL树,因为7的两颗子树的高度相差为2(以2为根节点的树的高度是3,而以8为根节点的树的高度是1)。

    2.节点的旋转

      如果在AVL树中进行插入或删除节点后,可能导致AVL树失去平衡。这种失去平衡的可以概括为4种姿态:LL(左左),LR(左右),RR(右右)和RL(右左)。下面给出它们的示意图:

      

      上图中的4棵树都是"失去平衡的AVL树",从左往右的情况依次是:LL、LR、RL、RR。除了上面的情况之外,还有其它的失去平衡的AVL树,如下图:

      

      上面的两张图都是为了便于理解,而列举的关于"失去平衡的AVL树"的例子。总的来说,AVL树失去平衡时的情况一定是LL、LR、RL、RR这4种之一,它们都由各自的定义:

      (1) LL:LeftLeft,也称为"左左"。插入或删除一个节点后,根节点的左子树的左子树还有非空子节点,导致"根的左子树的高度"比"根的右子树的高度"大2,导致AVL树失去了平衡。
         例如,在上面LL情况中,由于"根节点(8)的左子树(4)的左子树(2)还有非空子节点",而"根节点(8)的右子树(12)没有子节点";导致"根节点(8)的左子树(4)高度"比"根节点(8)的右子树(12)"高2。

      (2) LR:LeftRight,也称为"左右"。插入或删除一个节点后,根节点的左子树的右子树还有非空子节点,导致"根的左子树的高度"比"根的右子树的高度"大2,导致AVL树失去了平衡。
         例如,在上面LR情况中,由于"根节点(8)的左子树(4)的左子树(6)还有非空子节点",而"根节点(8)的右子树(12)没有子节点";导致"根节点(8)的左子树(4)高度"比"根节点(8)的右子树(12)"高2。

      (3) RL:RightLeft,称为"右左"。插入或删除一个节点后,根节点的右子树的左子树还有非空子节点,导致"根的右子树的高度"比"根的左子树的高度"大2,导致AVL树失去了平衡。
         例如,在上面RL情况中,由于"根节点(8)的右子树(12)的左子树(10)还有非空子节点",而"根节点(8)的左子树(4)没有子节点";导致"根节点(8)的右子树(12)高度"比"根节点(8)的左子树(4)"高2。

      (4) RR:RightRight,称为"右右"。插入或删除一个节点后,根节点的右子树的右子树还有非空子节点,导致"根的右子树的高度"比"根的左子树的高度"大2,导致AVL树失去了平衡。
         例如,在上面RR情况中,由于"根节点(8)的右子树(12)的右子树(14)还有非空子节点",而"根节点(8)的左子树(4)没有子节点";导致"根节点(8)的右子树(12)高度"比"根节点(8)的左子树(4)"高2。

      前面说过,如果在AVL树中进行插入或删除节点后,可能导致AVL树失去平衡。AVL失去平衡之后,可以通过旋转使其恢复平衡,下面分别介绍"LL(左左),LR(左右),RR(右右)和RL(右左)"这4种情况对应的旋转方法。

    2.1 LL的旋转

      LL失去平衡的情况,可以通过一次旋转让AVL树恢复平衡。如下图:

      

      图中左边是旋转之前的树,右边是旋转之后的树。从中可以发现,旋转之后的树又变成了AVL树,而且该旋转只需要一次即可完成。
      对于LL旋转,你可以这样理解为:LL旋转是围绕"失去平衡的AVL根节点"进行的,也就是节点k2;而且由于是LL情况,即左左情况,就用手抓着"左孩子,即k1"使劲摇。将k1变成根节点,k2变成k1的右子树,"k1的右子树"变成"k2的左子树"。

      代码如下:

     1 // LL:左左对应的情况(左单旋转)。
     2 template<class T>
     3 Node<T> * AVLTree<T>::leftLeftRotation(Node<T>* k2)
     4 {
     5     NodePointer k1 = NULL, k2ParentPtr = NULL;
     6 
     7     k1 = k2->left;
     8     if (k2 != root)
     9     {
    10         k2ParentPtr = k2->parent;
    11         if (k2ParentPtr->left == k2)
    12         {
    13             k2ParentPtr->left = k1;
    14         }
    15         else
    16         {
    17             k2ParentPtr->right = k1;
    18         }
    19         k1->parent = k2ParentPtr;
    20     }
    21     else
    22     {
    23         k1->parent = NULL;
    24     }
    25 
    26     k2->left = k1->right;
    27     k1->right = k2;
    28     k2->parent = k1;
    29 
    30     if (k2->left != NULL)
    31     {
    32         NodePointer tmpK2Left = k2->left;
    33         tmpK2Left->parent = k2;
    34     }
    35 
    36     return k1;
    37 }
    leftLeftRotation

    2.2 RR的旋转

      理解了LL之后,RR就相当容易理解了。RR是与LL对称的情况!RR恢复平衡的旋转方法如下:

      

      图中左边是旋转之前的树,右边是旋转之后的树。RR旋转也只需要一次即可完成。

      代码如下:

     1 // RR:右右对应的情况(右单旋转)。
     2 template<class T>
     3 Node<T> * AVLTree<T>::rightRightRotation(Node<T>* k1)
     4 {
     5     NodePointer k2 = NULL, k1ParentPtr = NULL;
     6 
     7     k2 = k1->right;
     8     if (k1 != root)
     9     {
    10         k1ParentPtr = k1->parent;
    11         if (k1ParentPtr->left == k1)
    12         {
    13             k1ParentPtr->left = k2;
    14         }
    15         else
    16         {
    17             k1ParentPtr->right = k2;
    18         }
    19         k2->parent = k1ParentPtr;
    20     }
    21     else
    22     {
    23         k2->parent = NULL;
    24     }
    25 
    26     k1->right = k2->left;
    27     k2->left = k1;
    28     k1->parent = k2;
    29 
    30     if (k1->right != NULL)
    31     {
    32         NodePointer tmpK1Right = k1->right;
    33         tmpK1Right->parent = k1;
    34     }
    35 
    36     return k2;
    37 }
    rightRightRotation

    2.3 LR的旋转

      LR失去平衡的情况,需要经过两次旋转才能让AVL树恢复平衡。如下图:

      

      第一次旋转是围绕"k1"进行的"RR旋转",第二次是围绕"k3"进行的"LL旋转"。

      代码如下:

    1 // LR:左右对应的情况(左双旋转)。
    2 template<class T>
    3 Node<T> * AVLTree<T>::leftRightRotation(Node<T>* k3)
    4 {
    5     k3->left = rightRightRotation(k3->left);
    6 
    7     return leftLeftRotation(k3);
    8 }
    leftRightRotation

    2.4 RL的旋转

      RL是与LR的对称情况!RL恢复平衡的旋转方法如下:

      

      第一次旋转是围绕"k3"进行的"LL旋转",第二次是围绕"k1"进行的"RR旋转"。

      代码如下:

    1 // RL:右左对应的情况(右双旋转)。
    2 template<class T>
    3 Node<T> * AVLTree<T>::rightLeftRotation(Node<T>* k1)
    4 {
    5     k1->right = leftLeftRotation(k1->right);
    6 
    7     return rightRightRotation(k1);
    8 }
    rightLeftRotation

    3.代码实现

      这里定义的AVL树的类如下:

     1 #include "BSTree.hpp"
     2 
     3 template<class T>
     4 class AVLTree : public BSTree<T>
     5 {
     6 public:
     7     AVLTree();
     8     virtual ~AVLTree();
     9     virtual bool addNode(T k, T val);                 // 覆盖BSTree中的addNode函数
    10     virtual bool delNode(T k);                        // 覆盖BSTree中的delNode函数
    11 
    12 private:
    13     Node<T> * findImbalanceNode(NodePointer ptr);
    14     // LL:左左对应的情况(左单旋转)。
    15     Node<T> * leftLeftRotation(NodePointer k2);
    16     // RR:右右对应的情况(右单旋转)。
    17     Node<T> * rightRightRotation(NodePointer k1);
    18     // LR:左右对应的情况(左双旋转)。
    19     Node<T> * leftRightRotation(NodePointer k3);
    20     // RL:右左对应的情况(右双旋转)。
    21     Node<T> * rightLeftRotation(NodePointer k1);
    22 
    23 };

      实现程序为:

      1 #ifndef AVLTREE_H
      2 #define AVLTREE_H
      3 
      4 #include "BSTree.hpp"
      5 
      6 template<class T>
      7 class AVLTree : public BSTree<T>
      8 {
      9 public:
     10     AVLTree();
     11     virtual ~AVLTree();
     12     virtual bool addNode(T k, T val);                // 覆盖BSTree中的addNode函数
     13     virtual bool delNode(T k);                        // 覆盖BSTree中的delNode函数
     14 
     15 private:
     16     Node<T> * findImbalanceNode(NodePointer ptr);
     17     // LL:左左对应的情况(左单旋转)。
     18     Node<T> * leftLeftRotation(NodePointer k2);
     19     // RR:右右对应的情况(右单旋转)。
     20     Node<T> * rightRightRotation(NodePointer k1);
     21     // LR:左右对应的情况(左双旋转)。
     22     Node<T> * leftRightRotation(NodePointer k3);
     23     // RL:右左对应的情况(右双旋转)。
     24     Node<T> * rightLeftRotation(NodePointer k1);
     25 
     26 };
     27 
     28 template<class T>
     29 AVLTree<T>::AVLTree()
     30 {
     31     root = NULL;
     32 }
     33 
     34 template<class T>
     35 AVLTree<T>::~AVLTree()
     36 {
     37     destroy();
     38     root = NULL;
     39 }
     40 
     41 template<class T>
     42 bool AVLTree<T>::addNode(T k, T val)
     43 {
     44     bool isSuccess = BSTree<T>::addNode(k, val);
     45     if (isSuccess)
     46     {
     47         NodePointer ptr = searchNode(k);
     48         if (ptr != root)
     49         {
     50             NodePointer preParent = ptr->parent;
     51             if (preParent != root)
     52             {
     53                 NodePointer prePreParent = preParent->parent;
     54                 if (prePreParent == root)
     55                 {
     56                     if (getHeight(prePreParent->left) - getHeight(prePreParent->right) == 2)
     57                     {
     58                         if (ptr == preParent->left)
     59                         {
     60                             root = leftLeftRotation(prePreParent);
     61                         }
     62                         else
     63                         {
     64                             root = leftRightRotation(prePreParent);
     65                         }
     66                     }
     67                     else if (getHeight(prePreParent->right) - getHeight(prePreParent->left) == 2)
     68                     {
     69                         if (ptr == preParent->left)
     70                         {
     71                             root = rightLeftRotation(prePreParent);
     72                         }
     73                         else
     74                         {
     75                             root = rightRightRotation(prePreParent);
     76                         }
     77                     }
     78                 }
     79                 else
     80                 {
     81                     NodePointer prePrePreParent = prePreParent->parent;
     82                     if (getHeight(prePreParent->left) - getHeight(prePreParent->right) == 2)
     83                     {
     84                         if (prePreParent == prePrePreParent->left)
     85                         {
     86                             if (ptr == preParent->left)
     87                             {
     88                                 prePrePreParent->left = leftLeftRotation(prePreParent);
     89                             }
     90                             else
     91                             {
     92                                 prePrePreParent->left = leftRightRotation(prePreParent);
     93                             }
     94                         }
     95                         else
     96                         {
     97                             if (ptr == preParent->left)
     98                             {
     99                                 prePrePreParent->right = leftLeftRotation(prePreParent);
    100                             }
    101                             else
    102                             {
    103                                 prePrePreParent->right = leftRightRotation(prePreParent);
    104                             }
    105                         }
    106                     }
    107                     else if (getHeight(prePreParent->right) - getHeight(prePreParent->left) == 2)
    108                     {
    109                         if (prePreParent == prePrePreParent->left)
    110                         {
    111                             if (ptr == preParent->left)
    112                             {
    113                                 prePrePreParent->left = rightLeftRotation(prePreParent);
    114                             }
    115                             else
    116                             {
    117                                 prePrePreParent->left = rightRightRotation(prePreParent);
    118                             }
    119                         }
    120                         else
    121                         {
    122                             if (ptr == preParent->left)
    123                             {
    124                                 prePrePreParent->right = rightLeftRotation(prePreParent);
    125                             }
    126                             else
    127                             {
    128                                 prePrePreParent->right = rightRightRotation(prePreParent);
    129                             }
    130                         }
    131                     }
    132                 }
    133             }
    134         }
    135     }
    136 
    137     return isSuccess;
    138 }
    139 
    140 template<class T>
    141 bool AVLTree<T>::delNode(T k)
    142 {
    143     bool isSuccess = true;
    144     NodePointer ptr = searchNode(k);
    145     NodePointer preParent = NULL;
    146     if (ptr != NULL)
    147     {
    148         if (ptr == root)
    149         {
    150             BSTree<T>::delNode(k);
    151             // only left left exist
    152             if (getHeight(root->left) - getHeight(root->right) == 2)
    153             {
    154                 root = leftLeftRotation(root);
    155             }
    156         }
    157         else
    158         {
    159             NodePointer lNode = NULL, rNode = NULL;
    160             preParent = ptr->parent;
    161             if (preParent == root)
    162             {
    163                 BSTree<T>::delNode(k);
    164                 lNode = root->left;
    165                 rNode = root->right;
    166                 if (getHeight(preParent->left) - getHeight(preParent->right) == 2)
    167                 {
    168                     if (getHeight(lNode->left) >= getHeight(lNode->right))
    169                     {
    170                         root = leftLeftRotation(preParent);
    171                     }
    172                     else
    173                     {
    174                         root = leftRightRotation(preParent);
    175                     }
    176                 }
    177                 else if (getHeight(preParent->right) - getHeight(preParent->left) == 2)
    178                 {
    179                     if (getHeight(rNode->right) >= getHeight(rNode->left))
    180                     {
    181                         root = rightRightRotation(preParent);
    182                     }
    183                     else
    184                     {
    185                         root = rightLeftRotation(preParent);
    186                     }
    187                 }
    188             }
    189             else
    190             {
    191                 NodePointer prePreParent = NULL;
    192                 NodePointer lNode = NULL, rNode = NULL;
    193                 BSTree<T>::delNode(k);
    194                 // 这里需要递归查找不平衡点,以防止高层结点不平衡而低层结点平衡的情况
    195                 NodePointer tmpPtr = findImbalanceNode(preParent);
    196                 if (tmpPtr != NULL)
    197                 {
    198                     if (tmpPtr == root)
    199                     {
    200                         lNode = tmpPtr->left;
    201                         rNode = tmpPtr->right;
    202                         if (getHeight(tmpPtr->left) - getHeight(tmpPtr->right) == 2)
    203                         {
    204                             if (getHeight(lNode->left) >= getHeight(lNode->right))
    205                             {
    206                                 root = leftLeftRotation(tmpPtr);
    207                             }
    208                             else
    209                             {
    210                                 root = leftRightRotation(tmpPtr);
    211                             }
    212                         }
    213                         else if (getHeight(tmpPtr->right) - getHeight(tmpPtr->left) == 2)
    214                         {
    215                             if (getHeight(rNode->right) >= getHeight(rNode->left))
    216                             {
    217                                 root = rightRightRotation(tmpPtr);
    218                             }
    219                             else
    220                             {
    221                                 root = rightLeftRotation(tmpPtr);
    222                             }
    223                         }
    224                     }
    225                     else
    226                     {
    227                         prePreParent = tmpPtr->parent;
    228                         lNode = tmpPtr->left;
    229                         rNode = tmpPtr->right;
    230                         if (getHeight(tmpPtr->left) - getHeight(tmpPtr->right) == 2)
    231                         {
    232                             if (tmpPtr == prePreParent->left)
    233                             {
    234                                 if (getHeight(lNode->left) >= getHeight(lNode->right))
    235                                 {
    236                                     prePreParent->left = leftLeftRotation(tmpPtr);
    237                                 }
    238                                 else
    239                                 {
    240                                     prePreParent->left = leftRightRotation(tmpPtr);
    241                                 }
    242                             }
    243                             else
    244                             {
    245                                 if (getHeight(lNode->left) >= getHeight(lNode->right))
    246                                 {
    247                                     prePreParent->right = leftLeftRotation(tmpPtr);
    248                                 }
    249                                 else
    250                                 {
    251                                     prePreParent->right = leftRightRotation(tmpPtr);
    252                                 }
    253                             }
    254                         }
    255                         else if (getHeight(tmpPtr->right) - getHeight(tmpPtr->left) == 2)
    256                         {
    257                             if (tmpPtr == prePreParent->left)
    258                             {
    259                                 if (getHeight(rNode->right) >= getHeight(rNode->left))
    260                                 {
    261                                     prePreParent->left = rightRightRotation(tmpPtr);
    262                                 }
    263                                 else
    264                                 {
    265                                     prePreParent->left = rightLeftRotation(tmpPtr);
    266                                 }
    267                             }
    268                             else
    269                             {
    270                                 if (getHeight(rNode->right) >= getHeight(rNode->left))
    271                                 {
    272                                     prePreParent->right = rightRightRotation(tmpPtr);
    273                                 }
    274                                 else
    275                                 {
    276                                     prePreParent->right = rightLeftRotation(tmpPtr);
    277                                 }
    278                             }
    279                         }
    280                     }
    281                 }
    282             }
    283         }
    284     }
    285     else
    286     {
    287         isSuccess = false;
    288     }
    289 
    290     return isSuccess;
    291 }
    292 
    293 
    294 template<class T>
    295 Node<T> * AVLTree<T>::findImbalanceNode(NodePointer ptr)
    296 {
    297     unsigned int lHeight = getHeight(ptr->left), rHeight = getHeight(ptr->right);
    298     if (ptr == NULL)
    299     {
    300         return NULL;
    301     }
    302     else
    303     {
    304         if (lHeight - rHeight == 2 || rHeight - lHeight == 2)
    305         {
    306             return ptr;
    307         }
    308         else
    309         {
    310             findImbalanceNode(ptr->parent);
    311         }
    312     }
    313 }
    314 
    315 // LL:左左对应的情况(左单旋转)。
    316 template<class T>
    317 Node<T> * AVLTree<T>::leftLeftRotation(Node<T>* k2)
    318 {
    319     NodePointer k1 = NULL, k2ParentPtr = NULL;
    320 
    321     k1 = k2->left;
    322     if (k2 != root)
    323     {
    324         k2ParentPtr = k2->parent;
    325         if (k2ParentPtr->left == k2)
    326         {
    327             k2ParentPtr->left = k1;
    328         }
    329         else
    330         {
    331             k2ParentPtr->right = k1;
    332         }
    333         k1->parent = k2ParentPtr;
    334     }
    335     else
    336     {
    337         k1->parent = NULL;
    338     }
    339 
    340     k2->left = k1->right;
    341     k1->right = k2;
    342     k2->parent = k1;
    343 
    344     if (k2->left != NULL)
    345     {
    346         NodePointer tmpK2Left = k2->left;
    347         tmpK2Left->parent = k2;
    348     }
    349 
    350     return k1;
    351 }
    352 
    353 // RR:右右对应的情况(右单旋转)。
    354 template<class T>
    355 Node<T> * AVLTree<T>::rightRightRotation(Node<T>* k1)
    356 {
    357     NodePointer k2 = NULL, k1ParentPtr = NULL;
    358 
    359     k2 = k1->right;
    360     if (k1 != root)
    361     {
    362         k1ParentPtr = k1->parent;
    363         if (k1ParentPtr->left == k1)
    364         {
    365             k1ParentPtr->left = k2;
    366         }
    367         else
    368         {
    369             k1ParentPtr->right = k2;
    370         }
    371         k2->parent = k1ParentPtr;
    372     }
    373     else
    374     {
    375         k2->parent = NULL;
    376     }
    377 
    378     k1->right = k2->left;
    379     k2->left = k1;
    380     k1->parent = k2;
    381 
    382     if (k1->right != NULL)
    383     {
    384         NodePointer tmpK1Right = k1->right;
    385         tmpK1Right->parent = k1;
    386     }
    387 
    388     return k2;
    389 }
    390 
    391 // LR:左右对应的情况(左双旋转)。
    392 template<class T>
    393 Node<T> * AVLTree<T>::leftRightRotation(Node<T>* k3)
    394 {
    395     k3->left = rightRightRotation(k3->left);
    396 
    397     return leftLeftRotation(k3);
    398 }
    399 
    400 // RL:右左对应的情况(右双旋转)。
    401 template<class T>
    402 Node<T> * AVLTree<T>::rightLeftRotation(Node<T>* k1)
    403 {
    404     k1->right = leftLeftRotation(k1->right);
    405 
    406     return rightRightRotation(k1);
    407 }
    408 
    409 
    410 #endif 
    AVLTree.hpp

      Boost单元测试程序为:

      1       
      2 #include "stdafx.h"
      3 #include "../AVLTree/AVLTree.hpp"
      4 
      5 struct AVLTree_Fixture
      6 {
      7 public:
      8     AVLTree_Fixture()
      9     {
     10         testAVLTree = new AVLTree<int>();
     11     }
     12     ~AVLTree_Fixture()
     13     {
     14         delete testAVLTree;
     15     }
     16 
     17     AVLTree<int> * testAVLTree;
     18 
     19 };
     20 
     21 BOOST_FIXTURE_TEST_SUITE(AVLTree_Test_Suite, AVLTree_Fixture)
     22 
     23 BOOST_AUTO_TEST_CASE( AVLTree_addNode_Test )  
     24 {
     25     // add node next next to root and cause "left left/right" imbalance
     26     // left left
     27     BOOST_REQUIRE(testAVLTree->addNode(5, 5) == true);
     28     BOOST_REQUIRE(testAVLTree->addNode(4, 4) == true);
     29     BOOST_REQUIRE(testAVLTree->addNode(3, 3) == true);
     30     testAVLTree->destroy();
     31     // left right
     32     BOOST_REQUIRE(testAVLTree->addNode(5, 5) == true);
     33     BOOST_REQUIRE(testAVLTree->addNode(3, 3) == true);
     34     BOOST_REQUIRE(testAVLTree->addNode(4, 4) == true);
     35     testAVLTree->destroy();
     36     // add node next next to root and cause "right left/right" imbalance
     37     // right left
     38     BOOST_REQUIRE(testAVLTree->addNode(5, 5) == true);
     39     BOOST_REQUIRE(testAVLTree->addNode(7, 7) == true);
     40     BOOST_REQUIRE(testAVLTree->addNode(6, 6) == true);
     41     testAVLTree->destroy();
     42     // right right
     43     BOOST_REQUIRE(testAVLTree->addNode(5, 5) == true);
     44     BOOST_REQUIRE(testAVLTree->addNode(7, 7) == true);
     45     BOOST_REQUIRE(testAVLTree->addNode(8, 8) == true);
     46     testAVLTree->destroy();
     47 
     48     // add node not next next to root and cause "left left/right" imbalance
     49     // left left
     50     BOOST_REQUIRE(testAVLTree->addNode(6, 6) == true);
     51     BOOST_REQUIRE(testAVLTree->addNode(5, 5) == true);
     52     BOOST_REQUIRE(testAVLTree->addNode(7, 7) == true);
     53     BOOST_REQUIRE(testAVLTree->addNode(3, 3) == true);
     54     BOOST_REQUIRE(testAVLTree->addNode(2, 2) == true);
     55     testAVLTree->destroy();
     56 
     57     // left right
     58     BOOST_REQUIRE(testAVLTree->addNode(6, 6) == true);
     59     BOOST_REQUIRE(testAVLTree->addNode(5, 5) == true);
     60     BOOST_REQUIRE(testAVLTree->addNode(7, 7) == true);
     61     BOOST_REQUIRE(testAVLTree->addNode(3, 3) == true);
     62     BOOST_REQUIRE(testAVLTree->addNode(4, 4) == true);
     63     testAVLTree->destroy();
     64 
     65     // add node next next to root and cause "right left/right" imbalance
     66     // right left
     67     BOOST_REQUIRE(testAVLTree->addNode(6, 6) == true);
     68     BOOST_REQUIRE(testAVLTree->addNode(5, 5) == true);
     69     BOOST_REQUIRE(testAVLTree->addNode(7, 7) == true);
     70     BOOST_REQUIRE(testAVLTree->addNode(10, 10) == true);
     71     BOOST_REQUIRE(testAVLTree->addNode(8, 8) == true);
     72     testAVLTree->destroy();
     73 
     74     // right right
     75     BOOST_REQUIRE(testAVLTree->addNode(6, 6) == true);
     76     BOOST_REQUIRE(testAVLTree->addNode(5, 5) == true);
     77     BOOST_REQUIRE(testAVLTree->addNode(7, 7) == true);
     78     BOOST_REQUIRE(testAVLTree->addNode(10, 10) == true);
     79     BOOST_REQUIRE(testAVLTree->addNode(11, 11) == true);
     80     testAVLTree->destroy();
     81 
     82 }
     83 
     84 BOOST_AUTO_TEST_CASE(AVLTree_delNode_Test)
     85 {
     86     // delete root and cause "right right" imbalance --------------------------------
     87     // actually, only "right right" imbalance will be caused at such condition ------
     88     int key1[] = { 5, 4, 6, 2 };
     89     int value1[] = { 5, 4, 6, 2 };
     90     unsigned len1 = sizeof(key1) / sizeof(int);
     91     testAVLTree->creatTree(key1, value1, len1);
     92     BOOST_REQUIRE(testAVLTree->delNode(5) == true);
     93     testAVLTree->destroy();
     94 
     95     // delete right node of 'root' and cause "left left/right" imbalance ----------------
     96     // left left
     97     int key31[] = { 6, 4, 7, 3, 5, 8, 2 };
     98     int value31[] = { 6, 4, 7, 3, 5, 8, 2 };
     99     unsigned len31 = sizeof(key31) / sizeof(int);
    100     testAVLTree->creatTree(key31, value31, len31);
    101     BOOST_REQUIRE(testAVLTree->delNode(7) == true);
    102     testAVLTree->destroy();
    103 
    104     // left right
    105     int key32[] = { 6, 3, 7, 2, 4, 8, 5 };
    106     int value32[] = { 6, 3, 7, 2, 4, 8, 5 };
    107     unsigned len32 = sizeof(key32) / sizeof(int);
    108     testAVLTree->creatTree(key32, value32, len32);
    109     BOOST_REQUIRE(testAVLTree->delNode(7) == true);
    110     testAVLTree->destroy();
    111 
    112     // delete left node of 'root' and cause "right left/right" imbalance -------------------
    113     // right left
    114     int key21[] = { 4, 3, 7, 2, 6, 9, 5 };
    115     int value21[] = { 4, 3, 7, 2, 6, 9, 5 };
    116     unsigned len21 = sizeof(key21) / sizeof(int);
    117     testAVLTree->creatTree(key21, value21, len21);
    118     BOOST_REQUIRE(testAVLTree->delNode(3) == true);
    119     testAVLTree->destroy();
    120     // right right
    121     int key22[] = { 5, 4, 7, 2, 6, 9, 10 };
    122     int value22[] = { 5, 4, 7, 2, 6, 9, 10 };
    123     unsigned len22 = sizeof(key22) / sizeof(int);
    124     testAVLTree->creatTree(key22, value22, len22);
    125     BOOST_REQUIRE(testAVLTree->delNode(4) == true);
    126     testAVLTree->destroy();
    127 
    128     // delete node and cause "left left/right" imbalance -------------------
    129     // left left -- imbalanced node is at root
    130     int key41[] = { 8, 5, 9, 4, 6, 10, 3 };
    131     int value41[] = { 8, 5, 9, 4, 6, 10, 3 };
    132     unsigned len41 = sizeof(key41) / sizeof(int);
    133     testAVLTree->creatTree(key41, value41, len41);
    134     BOOST_REQUIRE(testAVLTree->delNode(10) == true);
    135     testAVLTree->destroy();
    136 
    137     // left right -- imbalanced node is at root
    138     int key42[] = { 8, 5, 9, 4, 6, 10, 7 };
    139     int value42[] = { 8, 5, 9, 4, 6, 10, 7 };
    140     unsigned len42 = sizeof(key42) / sizeof(int);
    141     testAVLTree->creatTree(key42, value42, len42);
    142     BOOST_REQUIRE(testAVLTree->delNode(10) == true);
    143     testAVLTree->destroy();
    144 
    145     // left left -- imbalanced node is not at root
    146     int key43[] = { 5, 8, 3, 7, 9, 2, 4, 1 };
    147     int value43[] = { 5, 8, 3, 7, 9, 2, 4, 1 };
    148     unsigned len43 = sizeof(key43) / sizeof(int);
    149     testAVLTree->creatTree(key43, value43, len43);
    150     BOOST_REQUIRE(testAVLTree->delNode(4) == true);
    151     testAVLTree->destroy();
    152 
    153     // left right -- imbalanced node is not at root
    154     int key44[] = { 5, 8, 3, 7, 9, 1, 4, 2 };
    155     int value44[] = { 5, 8, 3, 7, 9, 1, 4, 2 };
    156     unsigned len44 = sizeof(key44) / sizeof(int);
    157     testAVLTree->creatTree(key44, value44, len44);
    158     BOOST_REQUIRE(testAVLTree->delNode(4) == true);
    159     testAVLTree->destroy();
    160 
    161     // delete node and cause "right left/right" imbalance -------------------
    162     // right left -- imbalanced node is at root
    163     int key51[] = { 8, 5, 11, 4, 10, 12, 9 };
    164     int value51[] = { 8, 5, 11, 4, 10, 12, 9 };
    165     unsigned len51 = sizeof(key51) / sizeof(int);
    166     testAVLTree->creatTree(key51, value51, len51);
    167     BOOST_REQUIRE(testAVLTree->delNode(4) == true);
    168     testAVLTree->destroy();
    169 
    170     // right right -- imbalanced node is at root
    171     int key52[] = { 8, 5, 11, 4, 10, 12, 13 };
    172     int value52[] = { 8, 5, 11, 4, 10, 12, 13 };
    173     unsigned len52 = sizeof(key52) / sizeof(int);
    174     testAVLTree->creatTree(key52, value52, len52);
    175     BOOST_REQUIRE(testAVLTree->delNode(4) == true);
    176     testAVLTree->destroy();
    177 
    178     // right left -- imbalanced node is not at root
    179     int key53[] = { 5, 8, 3, 7, 10, 1, 4, 2, 9 };
    180     int value53[] = { 5, 8, 3, 7, 10, 1, 4, 2, 9 };
    181     unsigned len53 = sizeof(key53) / sizeof(int);
    182     testAVLTree->creatTree(key53, value53, len53);
    183     BOOST_REQUIRE(testAVLTree->delNode(7) == true);
    184     testAVLTree->destroy();
    185 
    186     // right right -- imbalanced node is not at root
    187     int key54[] = { 5, 8, 3, 7, 9, 1, 4, 2, 10 };
    188     int value54[] = { 5, 8, 3, 7, 9, 1, 4, 2, 10 };
    189     unsigned len54 = sizeof(key54) / sizeof(int);
    190     testAVLTree->creatTree(key54, value54, len54);
    191     BOOST_REQUIRE(testAVLTree->delNode(7) == true);
    192     testAVLTree->destroy();
    193 
    194 }
    195 
    196 //BOOST_AUTO_TEST_CASE(AVLTree_CopyConstructor_Test)
    197 //{
    198 //    // leave blank
    199 //}
    200 //
    201 //BOOST_AUTO_TEST_CASE(AVLTree_EqualOperator_Test)
    202 //{
    203 //    // leave blank
    204 //}
    205 
    206 BOOST_AUTO_TEST_SUITE_END()
    AVTreeUnitTest

      本篇博文的代码均托管到Github.

  • 相关阅读:
    Android开发(三十二)——延时
    Android开发(三十一)——重复引用包错误Conversion to Dalvik format failed
    Android开发(二十九)——layout_weight的含义
    Android开发(二十八)——基础功能函数
    Android开发(二十七)——android:layout_weight的真实含义
    Android开发(二十六)——Application
    Android开发(二十五)——Android上传文件至七牛
    ansible
    H3C 交换机VRRP和堆叠
    Centos 7.x 双网卡绑定
  • 原文地址:https://www.cnblogs.com/xiehongfeng100/p/4165479.html
Copyright © 2020-2023  润新知