Descarga la aplicación para disfrutar aún más
Vista previa del material en texto
UNIVERSIDAD DE GUADALAJARA Centro Universitario de Ciencias Exactas e Ingenierías Estructura de datos I Actividad de Aprendizaje 13. El Árbol AVL, implementación dinámica Alumno: Sandoval Padilla Fernando Cesar Docente: Gutiérrez Hernández Alfredo Código: 215685409 Sección: D12 23 de Noviembre de 2019 Resumen personal: La realización de esta actividad fue bastante sencilla, así que solo fue necesario implementar el árbol AVL al primer árbol, lo cual no fue complejo logrando así hacer mas eficiente el programa para trabajar con un mayor número de elementos. Código fuente: Main.cpp 1 #include <iostream> 2 #include <chrono> 3 #include <random> 4 #include <functional> 5 6 #include "btree.h" 7 8 using namespace std; 9 10 int main() { 11 default_random_engine generator(chrono::system_clock::now().time_since_epoch().count()); 12 uniform_int_distribution<int> intDistribution(0, 100000); 13 auto intDice = bind(intDistribution, generator); 14 15 BTree<int> myArbol; 16 int data, cant; 17 18 cout<<"Cuantos numeros desea en su arbol? "; 19 cin>>cant; 20 21 22 try { 23 for(int i(0); i < cant; i++) { 24 data = intDice(); 25 cout << i+1 <<". Insertando: " << data << endl; 26 27 myArbol.insertData(data); 28 } 29 } 30 catch(BTree<int>::Exception ex) { 31 cout << ex.what() << endl; 32 } 33 34 cout << endl << endl; 35 36 cout << "Preorder = "; 37 myArbol.parsePreOrder(); 38 39 cout << endl << endl; 40 41 cout << "Inorder = "; 42 myArbol.parseInOrder(); 43 44 cout << endl << endl; 45 46 cout << "Postorder = "; 47 myArbol.parsePostOrder(); 48 49 cout << endl << endl; 50 51 cout << "Altura del subarbol Izquierdo: " << myArbol.getHeightLeft() << endl; 52 53 cout << endl << endl; 54 55 cout << "Altura del subarbol Derecho: " << myArbol.getHeightRight() << endl; 56 57 cout << endl << endl; 58 59 cout << "Altura del arbol: " << myArbol.getHeight() << endl; 60 61 cout << endl << endl; 62 63 return 0; 64 } btree.h 1 /* 2 Optimizar el arbol: 3 - atributo de saber cual es la altura de cada sub-arbol 4 - atributo de lista doblemente ligados (Cada hijo sabe cual es su padre) 5 6 Elemento faltante: 7 - Eliminar dato 8 */ 9 10 #ifndef BTREE_H_INCLUDED 11 #define BTREE_H_INCLUDED 12 13 #include <exception> 14 #include <string> 15 16 template <class T> 17 class BTree { 18 public: 19 class Node { 20 private: 21 T* dataPtr; 22 Node* left; 23 Node* right; 24 25 public: 26 class Exception : public std::exception { 27 private: 28 std::string msg; 29 30 public: 31 explicit Exception(const char* message) : msg(message) { } 32 33 explicit Exception(const std::string& message) : msg(message) { } 34 35 virtual ~Exception() throw () { } 36 37 virtual const char* what() const throw () { 38 return msg.c_str(); 39 } 40 }; 41 Node(); 42 Node(const T&); 43 44 ~Node(); 45 46 T* getDataPtr(); 47 T& getData(); 48 49 Node*& getLeft(); 50 Node*& getRight(); 51 52 void setDataPTr(T*); 53 void setData(const T&); 54 void setLeft(Node*&); 55 void setRight(Node*&); 56 }; 57 58 class Exception : public std::exception { 59 private: 60 std::string msg; 61 62 public: 63 explicit Exception(const char* message) : msg(message) { } 64 65 explicit Exception(const std::string& message) : msg(message) { } 66 67 virtual ~Exception() throw () { } 68 69 virtual const char* what() const throw () { 70 return msg.c_str(); 71 } 72 }; 73 74 private: 75 Node* root; 76 77 void copyAll(Node*&, Node*&); 78 79 void insertData(Node*&, const T&); 80 81 Node*& findData(Node*&, const T&); 82 83 void deleteAll(Node*&); 84 85 Node*& getTheLowest(Node*&); 86 87 Node*& getTheHighest(Node*&); 88 89 int getHeight(Node*&); 90 91 int getHeightRight(Node*&); 92 93 int getHeightLeft(Node*&); 94 95 void parsePreOrder(Node*&); 96 97 void parseInOrder(Node*&); 98 99 void parsePostOrder(Node*&); 100 101 int getBalanceFactor(Node*&); 102 103 void doSimpleLeftRot(Node*&); 104 105 void doSimpleRightRot(Node*&); 106 107 void doDoubleLeftRot(Node*&); 108 109 void doDoubleRightRot(Node*&); 110 111 void doBalancing(Node*&); 112 113 void swapData(T&, T&); 114 115 public: 116 BTree(); 117 BTree(const BTree&); 118 119 ~BTree(); 120 121 bool isEmpty() const; 122 123 void insertData(const T&); 124 125 Node*& findData(const T&); 126 127 T& retrieve(Node*&); 128 129 void parsePreOrder(); 130 131 void parseInOrder(); 132 133 void parsePostOrder(); 134 135 void deleteData(Node*&); 136 137 bool isLeaf(Node*&) const; 138 139 int getHeight(); 140 141 int getHeightRight(); 142 143 int getHeightLeft(); 144 145 void deleteAll(); 146 147 BTree& operator = (const BTree&); 148 }; 149 150 ///Nodo 151 152 template <class T> 153 BTree<T>::Node::Node() : dataPtr(nullptr), left(nullptr), right(nullptr) { } 154 155 template <class T> 156 BTree<T>::Node::Node(const T& e) : dataPtr(new T(e)), left(nullptr), right(nullptr) { 157 if(dataPtr == nullptr) { 158 throw Exception(" Memoria no disponible, creando nodo"); 159 } 160 } 161 162 template <class T> 163 BTree<T>::Node::~Node() { 164 delete dataPtr; 165 } 166 167 template <class T> 168 T* BTree<T>::Node::getDataPtr() { 169 return dataPtr; 170 } 171 172 template <class T> 173 T& BTree<T>::Node::getData() { 174 return *dataPtr; 175 } 176 177 template <class T> 178 typename BTree<T>::Node*& BTree<T>::Node::getLeft() { 179 return left; 180 } 181 182 template <class T> 183 typename BTree<T>::Node*& BTree<T>::Node::getRight() { 184 return right; 185 } 186 187 template <class T> 188 void BTree<T>::Node::setDataPTr(T* p) { 189 dataPtr = p; 190 } 191 192 template <class T> 193 void BTree<T>::Node::setData(const T& e) { 194 if(dataPtr == nullptr and (dataPtr = new T(e)) == nullptr) { 195 196 throw Exception(" Memoria no disponible, Node::setData"); 197 } 198 else { 199 *dataPtr = e; 200 } 201 } 202 203 template <class T> 204 void BTree<T>::Node::setLeft(BTree<T>::Node*& p) { 205 left = p; 206 } 207 208 template <class T> 209 void BTree<T>::Node::setRight(BTree<T>::Node*& p) { 210 right = p; 211 } 212 213 ///BTree 214 215 ///private 216 217 template <class T> 218 void BTree<T>::copyAll(Node*& orig, Node*& dest) { 219 if(orig == nullptr) { 220 return; 221 } 222 223 dest = new Node(orig->getData()); 224 225 copyAll(orig->getLeft(), dest->getLeft()); 226 copyAll(orig->getRight(), dest->getRight()); 227 } 228 229 template <class T> 230 void BTree<T>::insertData(BTree<T>::Node*& r, const T& e) { 231 if(r == nullptr) { ///Inserta como hoja (balanceada) (no recursivo) 232 try { 233 if((r = new Node(e)) == nullptr) { 234 throw Exception(" Memoria no disponible, insertData."); 235 } 236 } 237 catch(typename Node::Exception ex) { 238 throw Exception(ex.what()); 239 } 240 241 return; 242 } 243 244 ///Insercion recursiva 245 if(e < r->getData()) { 246 insertData(r->getLeft(), e); 247 } 248 else { 249 insertData(r->getRight(), e); 250 } 251 ///Aqui sale de la recursion 252 253 ///Revisar factor de equilibrio, aplicar rotaciones 254 doBalancing(r); 255 } 256 257 template <class T> 258 typename BTree<T>::Node*& BTree<T>::findData(BTree<T>::Node*& r, const T& e) { 259 if(r == nullptr or r->getData() == e) { 260 return r; 261 } 262 263 if(e < r->getData()) { 264 return findData(r->getLeft(), e); 265 } 266 else { 267 return findData(r->getRight(), e); 268 } 269 } 270 271 template <class T> 272 void BTree<T>::deleteAll(BTree<T>::Node*& r) { 273 if(r == nullptr) { 274 return; 275 } 276 277 deleteAll(r->getLeft()); 278 deleteAll(r->getRight()); 279 280 delete r; 281 282 r = nullptr; 283 } 284 285 template <class T> 286 typename BTree<T>::Node*& BTree<T>::getTheLowest(BTree<T>::Node*& r) { 287 if(r == nullptr or r->getLeft() == nullptr) { 288 return r; 289 } 290 291 return getTheLowest(r->getLeft()); 292 } 293 294 template <class T> 295 typename BTree<T>::Node*& BTree<T>::getTheHighest(BTree<T>::Node*& r) { 296 if(r == nullptr or r->getRight() == nullptr) { 297 return r; 298 } 299 300 return getTheHighest(r->getRight()); 301 } 302 303 template <class T> 304 int BTree<T>::getHeight(BTree<T>::Node*& r) { 305 if(r == nullptr) { 306 return 0; 307 } 308 309 int leftHeigth(getHeight(r->getLeft()));310 int rightHeigth(getHeight(r->getRight())); 311 312 return (leftHeigth > rightHeigth ? leftHeigth : rightHeigth) + 1; 313 } 314 315 template <class T> 316 int BTree<T>::getHeightRight(BTree<T>::Node*& r) { 317 if(r == nullptr) { 318 return 0; 319 } 320 321 int leftHeigth(getHeight(r->getLeft())); 322 int rightHeigth(getHeight(r->getRight())); 323 324 return (leftHeigth > rightHeigth ? leftHeigth : rightHeigth) + 1; 325 } 326 327 template <class T> 328 int BTree<T>::getHeightLeft(BTree<T>::Node*& r) { 329 if(r == nullptr) { 330 return 0; 331 } 332 333 int leftHeigth(getHeight(r->getLeft())); 334 int rightHeigth(getHeight(r->getRight())); 335 336 return (leftHeigth > rightHeigth ? leftHeigth : rightHeigth) + 1; 337 } 338 339 template <class T> 340 void BTree<T>::parsePreOrder(BTree<T>::Node*& r) { 341 if(r == nullptr) { 342 return; 343 } 344 345 std::cout << r->getData() << ", "; 346 parsePreOrder(r->getLeft()); 347 parsePreOrder(r->getRight()); 348 } 349 350 template <class T> 351 void BTree<T>::parseInOrder(BTree<T>::Node*& r) { 352 if(r == nullptr) { 353 return; 354 } 355 356 parseInOrder(r->getLeft()); 357 std::cout << r->getData() << ", "; 358 parseInOrder(r->getRight()); 359 } 360 361 template <class T> 362 void BTree<T>::parsePostOrder(BTree<T>::Node*& r) { 363 if(r == nullptr) { 364 return; 365 } 366 367 parsePostOrder(r->getLeft()); 368 parsePostOrder(r->getRight()); 369 std::cout << r->getData() << ", "; 370 } 371 372 373 template <class T> 374 void BTree<T>::swapData(T& a, T& b) { 375 T aux; 376 377 aux = a; 378 a = b; 379 b= aux; 380 } 381 382 ///public 383 384 template <class T> 385 BTree<T>::BTree() : root(nullptr) { } 386 387 template <class T> 388 BTree<T>::BTree(const BTree<T>& t) : root(nullptr) { 389 copyAll(t.root, root); 390 } 391 392 template <class T> 393 BTree<T>::~BTree() { 394 deleteAll(); 395 } 396 397 template <class T> 398 bool BTree<T>::isEmpty() const { 399 return root == nullptr; 400 } 401 402 template <class T> 403 void BTree<T>::insertData(const T& e) { 404 insertData(root, e); 405 } 406 407 template <class T> 408 typename BTree<T>::Node*& BTree<T>::findData(const T& e) { 409 return findData(root, e); 410 } 411 412 template <class T> 413 T& BTree<T>::retrieve(BTree<T>::Node*& r) { 414 if(r == nullptr) { 415 throw Exception(" Posicion invalida, retireve."); 416 } 417 418 return r->getData(); 419 } 420 421 template <class T> 422 void BTree<T>::parsePreOrder() { 423 parsePreOrder(root); 424 } 425 426 template <class T> 427 void BTree<T>::parseInOrder() { 428 parseInOrder(root); 429 } 430 431 template <class T> 432 void BTree<T>::parsePostOrder() { 433 parsePostOrder(root); 434 } 435 436 template <class T> 437 void BTree<T>::deleteData(BTree<T>::Node*& r) { 438 if(r == nullptr) { 439 throw Exception(" Posicion invalida, deleteData."); 440 } 441 442 if(isLeaf(r)) { 443 delete r; 444 445 r = nullptr; 446 447 return; 448 } 449 450 Node*& substitute(r->getLeft() != nullptr ? getTheHighest(r->getLeft()) : getTheLowest(r->getRight())); 451 452 swapData(r->getData(), substitute->getData()); 453 454 deleteData(substitute); 455 } 456 457 template <class T> 458 bool BTree<T>::isLeaf(BTree<T>::Node*& r) const { 459 return r != nullptr and r->getLeft() == r->getRight(); 460 } 461 462 template <class T> 463 int BTree<T>::getHeight() { 464 return getHeight(root); 465 } 466 467 template <class T> 468 int BTree<T>::getHeightRight() { 469 return getHeight(root->getRight()); 470 } 471 472 template <class T> 473 int BTree<T>::getHeightLeft() { 474 return getHeight(root->getLeft()); 475 } 476 477 template <class T> 478 void BTree<T>::deleteAll() { 479 deleteAll(root); 480 } 481 482 template <class T> 483 BTree<T>& BTree<T>::operator=(const BTree<T>& t) { 484 deleteAll(); 485 486 copyAll(t); 487 488 return *this; 489 } 490 491 template <class T> 492 int BTree<T>::getBalanceFactor(BTree<T>::Node*& r) { 493 return getHeight(r->getRight()) - getHeight(r->getLeft()); 494 } 495 496 template <class T> 497 void BTree<T>::doSimpleLeftRot(BTree<T>::Node*& r) { 498 Node* aux1(r->getRight()); 499 Node* aux2(aux1->getLeft()); 500 501 r->setRight(aux2); 502 aux1->setLeft(r); 503 r = aux1; 504 } 505 506 template <class T> 507 void BTree<T>::doSimpleRightRot(BTree<T>::Node*& r) { 508 Node* aux1(r->getLeft()); 509 Node* aux2(aux1->getRight()); 510 511 r->setLeft(aux2); 512 aux1->setRight(r); 513 r = aux1; 514 } 515 516 template <class T> 517 void BTree<T>::doDoubleLeftRot(BTree<T>::Node*& r) { 518 doSimpleRightRot(r->getRight()); 519 doSimpleLeftRot(r); 520 } 521 522 template <class T> 523 void BTree<T>::doDoubleRightRot(BTree<T>::Node*& r) { 524 doSimpleLeftRot(r->getLeft()); 525 doSimpleRightRot(r); 526 } 527 528 template <class T> 529 void BTree<T>::doBalancing(BTree<T>::Node*& r) { 530 switch(getBalanceFactor(r)) { 531 case 2: ///Desbalanceo a la derecha, aplicar rotacion a la izquierda. 532 if(getBalanceFactor(r->getRight()) == 1) { ///Coincide signo, simple 533 doSimpleLeftRot(r); 534 } 535 else { ///No coincide signo, doble 536 doDoubleLeftRot(r); 537 } 538 539 break; 540 541 case -2: ///Desbalanceo a la izquierda, aplicar rotacion a la derecha. 542 if(getBalanceFactor(r->getLeft()) == -1) { ///Coincide signo, simple 543 doSimpleRightRot(r); 544 } 545 else { ///No coincide signo, double 546 doDoubleRightRot(r); 547 } 548 549 break; 550 } 551 } 552 553 #endif // BTREE_H_INCLUDED Capturas de pantalla:
Compartir