AVL的实现
Posted gebicungaha
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AVL的实现相关的知识,希望对你有一定的参考价值。
1 #include "stdafx.h" 2 3 /* 4 * @author Wu Jingan 5 * @created June 6, 2018 6 */ 7 8 #include <iostream> 9 #include <string> 10 #include <algorithm> 11 #include <ctime> 12 #include <Windows.h> 13 #include <vector> 14 using namespace std; 15 16 class Node 17 { 18 public: 19 Node() {} 20 Node(int value, Node *parent, Node *left, Node *right) 21 { 22 this->value = value; 23 this->parent = parent; 24 this->left = left; 25 this->right = right; 26 } 27 28 Node operator=(const Node &_Right) 29 { 30 this->value = _Right.value; 31 this->parent = _Right.parent; 32 this->right = _Right.right; 33 this->left = _Right.left; 34 return *this; 35 } 36 37 bool isLeaf() 38 { 39 return this->left == nullptr && this->right == nullptr; 40 } 41 42 int value; 43 Node *parent; 44 Node *left; 45 Node *right; 46 }; 47 48 class AbstractBinarySearchTree 49 { 50 public: 51 int getMinimumNodeValue() 52 { 53 return getMinimumNode(root)->value; 54 } 55 56 int getMaximumNodeValue() 57 { 58 return getMaximumNode(root)->value; 59 } 60 61 int getSize() 62 { 63 return this->size; 64 } 65 66 //若元素不存在, 返回1 67 bool isContains(int element) 68 { 69 return search(element) == nullptr; 70 } 71 72 //先序遍历二叉搜索树 73 void printtAbstractBinarySearchTreePreOrder(Node *root) 74 { 75 if (root == nullptr) 76 return; 77 cout << root->value << " "; 78 printtAbstractBinarySearchTreePreOrder(root->left); 79 printtAbstractBinarySearchTreePreOrder(root->right); 80 } 81 82 //中序遍历二叉搜索树 83 void printtAbstractBinarySearchTreeInOrder(Node *root) 84 { 85 if (root == nullptr) 86 return; 87 printtAbstractBinarySearchTreeInOrder(root->left); 88 cout << root->value << " "; 89 printtAbstractBinarySearchTreeInOrder(root->right); 90 } 91 92 //后序遍历二叉搜索树 93 void printtAbstractBinarySearchTreePostOrder(Node *root) 94 { 95 if (root == nullptr) 96 return; 97 printtAbstractBinarySearchTreePostOrder(root->left); 98 printtAbstractBinarySearchTreePostOrder(root->right); 99 cout << root->value << " "; 100 } 101 102 void printTree() 103 { 104 printSubtree(root); 105 } 106 107 protected: 108 Node * createNode(int value, Node *parent, Node *left, Node *right) 109 { 110 Node *node = new Node(value, parent, left, right); 111 return node; 112 } 113 114 Node * deleteNode(int element) 115 { 116 Node *node = search(element); 117 if (node != nullptr) 118 return deleteNode(node); 119 else 120 return nullptr; 121 } 122 123 Node *search(int element) 124 { 125 Node *node = root; 126 while (node != nullptr && node->value != element) 127 { 128 if (node->value < element) 129 node = node->right; 130 else 131 node = node->left; 132 } 133 return node; 134 } 135 136 Node *insertNode(int element) 137 { 138 if (root == nullptr) 139 { 140 root = createNode(element, nullptr, nullptr, nullptr); 141 size++; 142 return root; 143 } 144 Node *insertParentNode = root; 145 Node *searchTempNode = root; 146 while (searchTempNode != nullptr) 147 { 148 insertParentNode = searchTempNode; 149 if (element < searchTempNode->value) 150 searchTempNode = searchTempNode->left; 151 else if (element > searchTempNode->value) 152 searchTempNode = searchTempNode->right; 153 else 154 return searchTempNode; 155 } 156 Node *NewNode = createNode(element, insertParentNode, nullptr, nullptr); 157 if (insertParentNode->value > element) 158 insertParentNode->left = NewNode; 159 else 160 insertParentNode->right = NewNode; 161 size++; 162 return NewNode; 163 } 164 165 Node * deleteNode(Node *deleteNode) 166 { 167 Node *nodeToReturn = nullptr; 168 if (deleteNode != nullptr) 169 { 170 if (deleteNode->left == nullptr) 171 nodeToReturn = transplantNode(deleteNode, deleteNode->right); 172 else if (deleteNode->right == nullptr) 173 nodeToReturn = transplantNode(deleteNode, deleteNode->left); 174 else 175 { 176 Node *successorNode = getMinimumNode(deleteNode->right); 177 if (successorNode->parent != deleteNode) 178 { 179 transplantNode(successorNode, successorNode->right); 180 successorNode->right = deleteNode->right; 181 successorNode->right->parent = successorNode; 182 } 183 transplantNode(deleteNode, successorNode); 184 successorNode->left = deleteNode->left; 185 successorNode->left->parent = successorNode; 186 nodeToReturn = successorNode; 187 } 188 size--; 189 return nodeToReturn; 190 } 191 else 192 return nullptr; 193 } 194 195 Node *transplantNode(Node *nodeToReplace, Node *newNode) 196 { 197 if (nodeToReplace->parent == nullptr) 198 this->root = newNode; 199 else if (nodeToReplace == nodeToReplace->parent->left) 200 nodeToReplace->parent->left = newNode; 201 else 202 nodeToReplace->parent->right = newNode; 203 if (newNode != nullptr) 204 newNode->parent = nodeToReplace->parent; 205 return newNode; 206 } 207 208 void printNodeValue(Node *node) 209 { 210 if (node == nullptr) 211 cout << "<null>"; 212 else 213 cout << node->value; 214 cout << endl; 215 } 216 217 void printSubtree(Node *node) 218 { 219 if (node->right != nullptr) { 220 printTree(node->right, true, ""); 221 } 222 printNodeValue(node); 223 if (node->left != nullptr) { 224 printTree(node->left, false, ""); 225 } 226 } 227 228 void printTree(Node *node, bool isRight, string indent) 229 { 230 if (node->right != nullptr) 231 printTree(node->right, true, indent + (isRight ? " " : " | ")); 232 cout << indent; 233 if (isRight) 234 cout << " /"; 235 else 236 cout << " \"; 237 cout << "----- "; 238 printNodeValue(node); 239 if (node->left != nullptr) 240 printTree(node->left, false, indent + (isRight ? " | " : " ")); 241 } 242 243 Node *getMinimumNode(Node *node) 244 { 245 while (node->left != nullptr) 246 node = node->left; 247 return node; 248 } 249 250 Node *getMaximumNode(Node *node) 251 { 252 while (node->right != nullptr) 253 node = node->right; 254 return node; 255 } 256 257 Node *root = nullptr; 258 int size; 259 }; 260 261 class AbstractSelfBalancingBinarySearchTree :public AbstractBinarySearchTree 262 { 263 protected: 264 Node * rotateLeft(Node *node) 265 { 266 Node *tempNode = node->right; 267 tempNode->parent = node->parent; 268 node->right = tempNode->left; 269 if (node->right != nullptr) 270 node->right->parent = node; 271 tempNode->left = node; 272 node->parent = tempNode; 273 if (tempNode->parent != nullptr) 274 { 275 if (node == tempNode->parent->left) 276 tempNode->parent->left = tempNode; 277 else 278 tempNode->parent->right = tempNode; 279 } 280 else 281 root = tempNode; 282 return tempNode; 283 } 284 285 Node *rotateRight(Node *node) 286 { 287 Node * tempNode = node->left; 288 tempNode->parent = node->parent; 289 node->left = tempNode->right; 290 if (node->left != nullptr) 291 node->left->parent = node; 292 293 tempNode->right = node; 294 node->parent = tempNode; 295 if (tempNode->parent != nullptr) 296 { 297 if (node == tempNode->parent->left) 298 tempNode->parent->left = tempNode; 299 else 300 tempNode->parent->right = tempNode; 301 } 302 else 303 root = tempNode; 304 return tempNode; 305 } 306 }; 307 308 class AVLNode :public Node 309 { 310 public: 311 AVLNode(int value, Node *parent, Node *left, Node *right) 312 { 313 Node(value, parent, left, right); 314 } 315 316 int height; 317 }; 318 319 class AVLTree :public AbstractSelfBalancingBinarySearchTree 320 { 321 public: 322 Node * insert(int element) 323 { 324 Node *newNode = this->insertNode(element); 325 rebalance((AVLNode *)newNode); 326 return newNode; 327 } 328 329 Node *deleteAVLNode(int element) 330 { 331 Node *delete_Node = AbstractSelfBalancingBinarySearchTree::search(element); 332 if (delete_Node != nullptr) 333 { 334 Node *successorNode = AbstractSelfBalancingBinarySearchTree::deleteNode(delete_Node); 335 if (successorNode != nullptr) 336 { 337 AVLNode *minimum = successorNode->right != nullptr ? (AVLNode *)getMinimumNode(successorNode->right) : (AVLNode *)successorNode; 338 recomputeHeight(minimum); 339 rebalance((AVLNode *)minimum); 340 } 341 else 342 { 343 recomputeHeight((AVLNode *)delete_Node->parent); 344 rebalance((AVLNode *)delete_Node->parent); 345 } 346 return successorNode; 347 } 348 return nullptr; 349 } 350 351 protected: 352 Node * createNode(int value, Node *parent, Node *left, Node *right) 353 { 354 return new AVLNode(value, parent, left, right); 355 } 356 357 Node * doubleRotateRightLeft(Node *node) 358 { 359 node->right = avlRotateRight(node->right); 360 return avlRotateLeft(node); 361 } 362 363 Node * doubleRotateLeftRight(Node *node) 364 { 365 node->left = avlRotateLeft(node->left); 366 return avlRotateRight(node); 367 } 368 369 private: 370 void rebalance(AVLNode *node) 371 { 372 while (node != nullptr) 373 { 374 Node *parent = node->parent; 375 376 int leftHeight = (node->left == nullptr) ? -1 : ((AVLNode *)node->left)->height; 377 int rightHeight = (node->right == nullptr) ? -1 : ((AVLNode *)node->right)->height; 378 int nodeBalance = leftHeight - rightHeight; 379 if (nodeBalance == -2) 380 { 381 if (node->right->right != nullptr) 382 { 383 node = (AVLNode *)avlRotateLeft(node); 384 break; 385 } 386 else 387 { 388 node = (AVLNode *)doubleRotateRightLeft(node); 389 break; 390 } 391 } 392 else if (nodeBalance == 2) 393 { 394 if (node->left->left != nullptr) 395 { 396 node = (AVLNode *)avlRotateRight(node); 397 break; 398 } 399 else 400 { 401 node = (AVLNode *)doubleRotateLeftRight(node); 402 break; 403 } 404 } 405 else 406 updateHeight(node); 407 node = (AVLNode*)parent; 408 } 409 410 } 411 412 void recomputeHeight(AVLNode *node) 413 { 414 while (node != nullptr) 415 { 416 node->height = maxHeight((AVLNode *)node->left, (AVLNode *)node->right) + 1; 417 node = (AVLNode *)node->parent; 418 } 419 } 420 421 int maxHeight(AVLNode *_LeftNode, AVLNode *_RightNode) 422 { 423 if (_LeftNode != nullptr && _RightNode != nullptr) 424 return _LeftNode->height > _RightNode->height ? _LeftNode->height : _RightNode->height; 425 else if (_LeftNode == nullptr) 426 return _RightNode != nullptr ? _RightNode->height : -1; 427 else if (_RightNode == nullptr) 428 return _LeftNode != nullptr ? _LeftNode->height : -1; 429 return -1; 430 } 431 432 Node * avlRotateLeft(Node *node) 433 { 434 Node *temp = AbstractSelfBalancingBinarySearchTree::rotateLeft(node); 435 updateHeight((AVLNode *)temp->left); 436 updateHeight((AVLNode *)temp); 437 return temp; 438 } 439 440 Node * avlRotateRight(Node *node) 441 { 442 Node *temp = AbstractSelfBalancingBinarySearchTree::rotateRight(node); 443 444 updateHeight((AVLNode *)temp->right); 445 updateHeight((AVLNode *)temp); 446 return temp; 447 } 448 449 void updateHeight(AVLNode *node) 450 { 451 int leftHeight = (node->left == nullptr) ? -1 : ((AVLNode *)node->left)->height; 452 int rightHeight = (node->right == nullptr) ? -1 : ((AVLNode *)node->right)->height; 453 node->height = max(leftHeight, rightHeight) + 1; 454 } 455 }; 456 457 //for test 458 class RandomArray 459 { 460 public: 461 RandomArray() { } 462 RandomArray(int maxValue, int maxSize) 463 { 464 this->maxValue = maxValue; 465 this->maxSize = maxSize; 466 this->randomVec = new vector<int>(rand() % maxSize + 5); 467 } 468 469 vector<int> *getRandomArray() 470 { 471 for (vector<int>::size_type i = 0; i < randomVec->size(); i++) 472 (*randomVec)[i] = rand() % maxValue + 1; 473 return randomVec; 474 } 475 476 int getSize() 477 { 478 return (int)randomVec->size(); 479 } 480 481 private: 482 int maxValue; 483 int maxSize; 484 vector<int> *randomVec; 485 }; 486 487 int main() 488 { 489 srand((unsigned)time(NULL)); 490 RandomArray randomArray(100, 15); 491 vector<int> *randomVec = randomArray.getRandomArray(); 492 AVLTree AVLtree; 493 AVLNode *root = (AVLNode *)AVLtree.insert((*randomVec)[0]); 494 cout << "the array for test is : " << (*randomVec)[0] << " "; 495 for (int i = 1; i < randomArray.getSize(); i++) 496 { 497 cout << (*randomVec)[i] << " "; 498 AVLtree.insert((*randomVec)[i]); 499 } 500 cout << endl; 501 502 AVLtree.printTree(); 503 504 cout << "============================" << endl; 505 506 int randomIndex = rand() % randomArray.getSize(); 507 cout << "the value of delete AVLnode is : " << (*randomVec)[randomIndex] << endl; 508 AVLtree.deleteAVLNode((*randomVec)[randomIndex]); 509 AVLtree.printTree(); 510 511 512 return 0; 513 }
以上是关于AVL的实现的主要内容,如果未能解决你的问题,请参考以下文章
C++_AVL树插入,查找与修改的实现(Key_Value+平衡因子+三叉链)