"《算法导论》之‘树’":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.

原文地址:https://www.cnblogs.com/xiehongfeng100/p/4165479.html