"《算法导论》之‘树’":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 }
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 }
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 }
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 }
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
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()
本篇博文的代码均托管到Github.